用C語言開發NES遊戲(CC65)10、遊戲循環

粘貼到CSDN格式沒調,想看格式好的點下面

https://happysoul.github.io/nes/nesdoug/

 

我們來談談遊戲循環

遊戲需要循環,while(1){}

 

循環裏的第一項是ppu_wait_nmi(),他會等待新一幀的開始觸發nmi,每秒60幀(歐版是50幀)

但是,如果遊戲的邏輯太過複雜將會耗費更多的時間,並且超過了nmi觸發的開始,那麼等到了ppu_wait_nmi()之後,他會等待下一幀,這樣會讓遊戲變得很慢。

好在現在還沒發生過這種情況,因爲我們的代碼太短了,但是後面做的遊戲中就不那麼簡單了,所以還是要注意代碼的簡潔。

 

控制器使用了

pad_poll(0)

get_pad_new(0)

 

然後要說的是clear_vram_buffer(),這些代碼對我來說是對一無二的。由於nmi的作用,我們需要重寫他,以便讓他能實現更多功能

score_lives_draw() 使用one_vram_buffer() 重新顯示屏幕頂端的計分板。

這些類似vram_put(),但他們將被放在緩衝區中,並且nmi代碼將在v-blank期間自動將它們推送到ppu。

 

 

然後是遊戲的邏輯,移動球拍,移動球,檢查是否有碰撞。

移動手柄

 


 

 

if(pad1 & PAD_LEFT){

Paddle.X -= 2;

if(Paddle.X < PADDLE_MIN) Paddle.X = PADDLE_MIN;

}

if(pad1 & PAD_RIGHT){

Paddle.X += 2;

if(Paddle.X > PADDLE_MAX) Paddle.X = PADDLE_MAX;

}

 

 

 

移動球,如果他是移動的

 


 

 

if(ball_direction == GOING_UP){

Ball.Y -= 3;

if(Ball.Y < MAX_UP){

ball_direction = GOING_DOWN;

}

}

else { // going down

Ball.Y += 3;

if(Ball.Y > MAX_DOWN){

--lives01;

ball_state = BALL_OFF;

}

}

 

 

 

然後到了繪製精靈,首先先要清除舊的,然後重新繪製所有活動的精靈。

 

如果一個塊被球命中,hit_block(),從碰撞圖中刪除這個塊,用一個空白塊填充這個區域。

同樣,我使用vram緩衝區暫時存儲它,並在v-blank期間自動將其發送到PPU。

 

通常情況下,我會使用很多個

game_states:比如標題,遊戲,暫停,結束。

我使用不同的 ball_states:飛出屏幕BALL_OFF,準備發射球BALL_STUCK (卡在平板邊緣),球在移動BALL_ACTIVE

 

我使用NES Screen Tool製作背景,在c1.csv中定義了可以破壞的圖塊。我沒用Tiled工具,因爲他顯示容易,但是如果有修改對應的可破壞的圖塊佈局也需要跟着修改(也就是前面的c1.csv)

 

 


 

 

const unsigned char c1 [] = {

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,

0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,

0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,

0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,

0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,

0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,

0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,

 

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

};

 

 

 

使用灰色的磚塊在NES Screen Tool中畫圖,然後壓縮導出RLE文件。

 

 

我在NES Screen Tool中預先更改了屬性表,然後保存背景。這就是瓷磚的顏色,它們是不同的調色板。但他們都使用相同的瓷磚。這是屬性檢查器視圖(按“A”)。

 

 

每幀都會更新記分牌,請注意我將得分的每個數字都保存爲單獨的變量(等級爲0-9)

score10是10位數,score01是個位數。由於6502處理器缺少內置數學運算,因此除法和模數對NES的操作非常慢,因此保持每個數字分開可加快代碼速度。

 

 

https://github.com/nesdoug/12_Break

 

現在把這個變成遊戲已經很簡單了,但是橫向移動需要寫很複雜的代碼,我會把示例寫的儘可能簡單。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章