如何在C语言及Processing中实现局部滚动,保持侧边元素固定?
问题1:C语言环境下实现局部滚动(侧边内容固定)
局部滚动的核心是仅刷新指定区域内容,保持其他区域不变,具体实现依赖你使用的终端/图形库:
终端环境(Linux/macOS)
用ncurses库是最直接的方案,通过划分独立窗口实现:
- 用
newwin()创建两个窗口:一个侧边固定窗口,一个可滚动内容窗口 - 对内容窗口调用
scrollok(win, TRUE)开启滚动,用wscrl(win, n)控制滚动行数 - 仅刷新内容窗口(
wrefresh(win)),侧边窗口保持不动
示例代码片段:
#include <ncurses.h> int main() { initscr(); // 创建侧边固定窗口(宽度20,全屏高度) WINDOW *side_win = newwin(LINES, 20, 0, 0); // 创建滚动内容窗口(从x=21开始,占剩余宽度) WINDOW *scroll_win = newwin(LINES, COLS-20, 0, 20); scrollok(scroll_win, TRUE); // 侧边窗口写入固定内容 wprintw(side_win, "固定侧边内容"); wrefresh(side_win); // 模拟滚动内容 for(int i=0; i<50; i++){ wprintw(scroll_win, "选项%d\n", i); wrefresh(scroll_win); getch(); // 按任意键滚动 wscrl(scroll_win, 1); // 向下滚动1行 } endwin(); return 0; }
Windows图形界面(Win32 API)
- 给滚动区域单独创建子窗口(
CreateWindowEx) - 处理
WM_VSCROLL消息,用ScrollWindowEx仅刷新子窗口区域 - 侧边固定元素直接绘制在主窗口,不随子窗口滚动
核心思路是把按钮区域当作可平移的独立画布,仅在该区域内处理按钮的绘制与交互,侧边元素直接绘制在主窗口:
1. 定义基础参数
// 滚动区域边界 float scrollAreaX = 200; float scrollAreaY = 50; float scrollAreaW = width - 250; float scrollAreaH = height - 100; // 滚动偏移量(控制按钮上下移动) float scrollOffset = 0; // 存储按钮的列表 ArrayList<BuildingButton> buttons = new ArrayList<>(); // 饼干数量(示例变量) int cookieCount = 0;
2. 创建按钮类
class BuildingButton { String name; float cost; float x, y; float w = 200; float h = 50; BuildingButton(String n, float c, float yPos) { name = n; cost = c; x = scrollAreaX + 10; y = yPos; } void draw() { // 绘制按钮时叠加滚动偏移量 rect(x, y + scrollOffset, w, h); text(name + " : " + (int)cost, x+10, y+scrollOffset+25); } boolean isHovered() { // 交互判断也要考虑滚动偏移 return mouseX > x && mouseX < x+w && mouseY > y+scrollOffset && mouseY < y+scrollOffset+h; } }
3. 初始化与绘制逻辑
void setup() { size(800, 600); // 添加示例按钮 buttons.add(new BuildingButton("Cursor", 15, 10)); buttons.add(new BuildingButton("Grandma", 100, 70)); buttons.add(new BuildingButton("Farm", 1100, 130)); buttons.add(new BuildingButton("Mine", 12000, 190)); } void draw() { background(255); // 绘制侧边固定元素 fill(200); rect(0, 0, 190, height); text("饼干数量: " + cookieCount, 20, 50); rect(20, 100, 150, 150); // 大点击按钮 // 绘制滚动区域边框 stroke(0); noFill(); rect(scrollAreaX, scrollAreaY, scrollAreaW, scrollAreaH); // 绘制所有按钮 for (BuildingButton b : buttons) { b.draw(); } }
4. 滚动与交互处理
void mouseWheel(MouseEvent event) { float scrollStep = event.getCount() * 10; // 限制滚动范围,避免滚出按钮区域 float maxScroll = -((buttons.size() * 60) - scrollAreaH); scrollOffset = constrain(scrollOffset - scrollStep, maxScroll, 0); } void mousePressed() { // 检测大点击按钮 if (mouseX > 20 && mouseX < 170 && mouseY > 100 && mouseY < 250) { cookieCount++; } // 检测按钮购买 for (BuildingButton b : buttons) { if (b.isHovered() && cookieCount >= b.cost) { cookieCount -= b.cost; // 这里添加建筑购买后的逻辑(比如增加饼干产量) } } }
额外提示
- 可以给滚动区域添加滚动条:根据
scrollOffset计算滚动条位置,用矩形绘制即可 - 如果按钮数量极大,可按需加载按钮(新手先实现全量加载版本更简单)
内容的提问来源于stack exchange,提问作者Pau De Alba Viñas
相关产品推荐
相关产品推荐

