gpt4 book ai didi

c - 在 C/Gameboy 编程中使用两个数组

转载 作者:太空狗 更新时间:2023-10-29 15:38:54 25 4
gpt4 key购买 nike

对于 Gameboy 编程中的游戏,我使用了四个数组,分别称为 topoldTopbottomoldBottom:

struct Point { int x, y; };
struct Rect { struct Point xx, yy; };

Rect top[size], oldTop[size];
Rect bottom[size], oldBottom[i];

其中 Rect 是由两个结构点组成的结构,即左上角点和右下角点。

该游戏的想法是让高度随机的方 block 从天花板上自上而下,从地板上自下而上。它类似于直升机经典游戏。在我的无限 while 循环中,我使用以下代码将所有矩形向下移动一个像素

while (1)
{
for (int i = 0; i < size; i++)
{
//in Struct Rect, xx is the top-left corner point, and yy is the bottom right
top[i].xx.x--;
top[i].yy.x--;
bottom[i].xx.x--;
bottom[i].yy.x--;

if (top[i].xx.x < 0)
{
top[i].xx.x += 240;
top[i].yy.x += 240;
}

if (bottom[i].xx.x < 0)
{
bottom[i].xx.x += 240;
bottom[i].yy.x += 240;
}
}

for (int i = 0; i < size; i++)
{
drawRect(oldTop[i], colorBlack);
drawRect(oldBottom[i], colorBlack);
}

/*call delay function that wait for Vertical Blank*/
for(int i = 0; i < size; i++)
{
drawRect(top[i], colorGreen);
drawRect(bottom[i], colorGreen);
oldTop[i] = top[i];
oldBottom[i] = bottom[i];
}
}

drawRect 方法使用 DMA 绘制矩形。

使用这段代码,代码应该像这样显示矩形:(用画图绘制) enter image description here

但是我得到的结果是

enter image description here

奇怪的是,如果我根本不绘制底行,那么顶行就可以正常绘制。当我同时绘制两者时,结果只会搞砸。这真的很奇怪,因为我认为代码应该可以正常工作,而且代码不是很复杂。发生这种情况是否有特定原因,有没有办法解决这个问题?

谢谢。

我用来绘制矩形的代码如下所示:

void drawRect(int row, int col, int width, int height){
int i;
for (i=0; i<height; i++)
{
DMA[3].src = &color;
DMA[3].dst = videoBuffer + (row+r)*240 + col);
DMA[3].cnt = DMA_ON | DMA_FIXED_SOURCE | width;
}
}

最佳答案

这是基于您的代码的调试 SSCCE (Short, Self-Contained, Correct Example)。这段代码中有断言会触发;它运行,但已知不正确。我已将 bottom 重命名为 btm 并将 oldBottom 重命名为 oldBtm 以便名称是对称的;它使代码布局更加系统化(但在其他方面无关紧要)。

#include <assert.h>
#include <stdio.h>

typedef struct Point { int x, y; } Point;
typedef struct Rect { struct Point xx, yy; } Rect;
enum { size = 2 };
typedef enum { colourGreen = 0, colourBlack = 1 } Colour;

/*ARGSUSED*/
static void drawRect(Rect r, Colour c)
{
printf(" (%3d)(%3d)", r.xx.x, r.yy.x);
}

int main(void)
{
Rect top[size], oldTop[size];
Rect btm[size], oldBtm[size];
int counter = 0;

for (int i = 0; i < size; i++)
{
top[i].xx.x = 240 - 4 * i;
top[i].xx.y = 0 + 10 + i;
top[i].yy.x = 240 - 14 * i;
top[i].yy.y = 0 + 20 + i;
btm[i].xx.x = 0 + 72 * i;
btm[i].xx.y = 0 + 10 * i;
btm[i].yy.x = 0 + 12 * i;
btm[i].yy.y = 0 + 20 * i;
oldTop[i] = top[i];
oldBtm[i] = btm[i];
}

while (1)
{
if (counter++ > 480) // Limit amount of output!
break;
for (int i = 0; i < size; i++)
{
//in Struct Rect, xx is the top-left corner point, and yy is the bottom right
top[i].xx.x--;
top[i].yy.x--;
btm[i].xx.x--;
btm[i].yy.x--;

if (top[i].xx.x < 0)
{
top[i].xx.x += 240;
top[i].yy.x += 240;
}

if (btm[i].xx.x < 0)
{
btm[i].xx.x += 240;
btm[i].yy.x += 240;
}
}

for (int i = 0; i < size; i++)
{
assert(top[i].xx.x >= 0 && top[i].yy.x >= 0);
assert(btm[i].xx.x >= 0 && btm[i].yy.x >= 0);
}

for (int i = 0; i < size; i++)
{
drawRect(oldTop[i], colourBlack);
drawRect(oldBtm[i], colourBlack);
}

/*call delay function that wait for Vertical Blank*/
for(int i = 0; i < size; i++)
{
drawRect(top[i], colourGreen);
drawRect(btm[i], colourGreen);
oldTop[i] = top[i];
oldBtm[i] = btm[i];
}
putchar('\n');
}
return(0);
}

如后期评论所述,此代码与您的代码之间的一大区别是您代码中的 oldBottom 声明为:

Rect top[size], oldTop[size];
Rect bottom[size], oldBottom[i];

使用尺寸 i 而不是 size。这可能是您看到的数组覆盖问题的原因。

还有第二个问题;中间火循环中的断言:

 (240)(240) (  0)(  0) (236)(226) ( 72)( 12) (239)(239) (239)(239) (235)(225) ( 71)( 11)
(239)(239) (239)(239) (235)(225) ( 71)( 11) (238)(238) (238)(238) (234)(224) ( 70)( 10)
(238)(238) (238)(238) (234)(224) ( 70)( 10) (237)(237) (237)(237) (233)(223) ( 69)( 9)
(237)(237) (237)(237) (233)(223) ( 69)( 9) (236)(236) (236)(236) (232)(222) ( 68)( 8)
(236)(236) (236)(236) (232)(222) ( 68)( 8) (235)(235) (235)(235) (231)(221) ( 67)( 7)
(235)(235) (235)(235) (231)(221) ( 67)( 7) (234)(234) (234)(234) (230)(220) ( 66)( 6)
(234)(234) (234)(234) (230)(220) ( 66)( 6) (233)(233) (233)(233) (229)(219) ( 65)( 5)
(233)(233) (233)(233) (229)(219) ( 65)( 5) (232)(232) (232)(232) (228)(218) ( 64)( 4)
(232)(232) (232)(232) (228)(218) ( 64)( 4) (231)(231) (231)(231) (227)(217) ( 63)( 3)
(231)(231) (231)(231) (227)(217) ( 63)( 3) (230)(230) (230)(230) (226)(216) ( 62)( 2)
(230)(230) (230)(230) (226)(216) ( 62)( 2) (229)(229) (229)(229) (225)(215) ( 61)( 1)
(229)(229) (229)(229) (225)(215) ( 61)( 1) (228)(228) (228)(228) (224)(214) ( 60)( 0)
Assertion failed: (btm[i].xx.x >= 0 && btm[i].yy.x >= 0), function main, file video.c, line 63.

我认为您的“非负面”检查应修改为:

            if (top[i].xx.x < 0)
top[i].xx.x += 240;
if (top[i].yy.x < 0)
top[i].yy.x += 240;

if (btm[i].xx.x < 0)
btm[i].xx.x += 240;
if (btm[i].yy.x < 0)
btm[i].yy.x += 240;

这会阻止任何负面影响。但是,完全合理的是,您应该使用原始 block 简单地检查右下角的 x 坐标(而不是左上角的坐标)。或者环绕可能需要更加复杂。那是给你破译的。但我认为出现奇怪的显示是因为您在不打算也不应该提供的地方提供了负值。

这里需要注意的重点是:

  1. 调试算法时,您不必使用正常的显示机制。
  2. 调试时,尽可能减少循环大小 (size == 2)。
  3. 仅打印相关信息(此处为 x 坐标)有助于减少输出。
  4. 使用计数器代码来限制输出量可以简化事情。
  5. 如果出现问题,尽早找出问题的规律。

在我得到显示的设计之前,我有各种版本的 drawRect() 函数,它在宽屏幕(例如 120x65)终端窗口上运行良好。

关于c - 在 C/Gameboy 编程中使用两个数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15727479/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com