⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 GBA躲壁球游戏
💻 C
字号:
/*
  VECTOR PONG GAME
  
  Author: Jonathan Harbour
  Date: January, 2007
  
  This game is pretty much finished, although the code is very minimal in order to make it
  as educational as possible. Converting it to sprites instead of vectors would be the single
  most beneficial improvement to the game but this is supposed to be a vector demonstration.

*/

#include <stdlib.h>
#include <stdio.h>
#include "font.h"

//some useful colors
#define BLACK 0x0000
#define WHITE 0xFFFF
#define BLUE 0xEE00
#define CYAN 0xFF00
#define GREEN 0x0EE0
#define RED 0x00FF
#define MAGENTA 0xF00F
#define BROWN 0x0D0D

//defines for the video system
unsigned short* videoBuffer = (unsigned short*)0x6000000;
#define DISPLAY_CONTROLLER *(unsigned long*)0x4000000
#define VIDC_BASE_HALF	((volatile unsigned short int*) 0x04000000)	
#define VCOUNT		(VIDC_BASE_HALF[3])	

#define VIDEO_MODE_3 0x3
#define BACKGROUND2 0x400
#define SCREEN_W 240
#define SCREEN_H 160

//game constants
#define BALL_SIZE 6
#define PADDLE_WIDTH 8
#define PADDLE_HEIGHT 28
#define PADDLE_SPEED 2

//global variables
int paddleX[3];
int paddleY[3];
int ballX, ballY;
int velX = 2, velY = 1;
int score1=0,score2=0;

void setMode(int mode)
{
    DISPLAY_CONTROLLER = mode | BACKGROUND2;
}

inline void drawpixel(int x, int y, unsigned short color)
{
	videoBuffer[y * 240 + x] = color;
}

inline unsigned short getpixel(int x, int y)
{
    return videoBuffer[y * 240 + x];
}

void drawbox(int left, int top, int right, int bottom, unsigned short color)
{
	int x, y;
    for(y = top; y < bottom; y++)
        for(x = left; x < right; x++)
            drawpixel(x, y, color);
}

int buttonPressed(int button)
{
    //pointer to the button interface
    volatile unsigned int *BUTTONS = (volatile unsigned int *)0x04000130;
    
    //see if UP button is pressed
    if (!((*BUTTONS) & button))
        return 1;
    else
        return 0;
}

//draw text using characters contained in font.h
void print(int left, int top, char *str, unsigned short color)
{
    int x, y, draw;
    int pos = 0;
    char letter;
    
    //look at all characters in this string
    while (*str)
    {
        //get current character ASCII code
        letter = (*str++) - 32;
        
        //draw the character
        for(y = 0; y < 8; y++)
            for(x = 0; x < 8; x++)
            {
                //grab a pixel from the font character
                draw = font[letter * 64 + y * 8 + x];
                
                //if pixel = 1, then draw it
                if (draw)
                    drawpixel(left + pos + x, top + y, color);
            }

        //jump over 8 pixels
        pos += 8;
    }
}

void printScores()
{
    char s[5];

    //erase scores
    drawbox(0,0,20,10,BLACK);
    drawbox(220,0,239,10,BLACK);

    //display scores
    sprintf(s,"%i",score1);
    print(5,0,s,WHITE);
    
    sprintf(s,"%i",score2);
    print(220,0,s,WHITE);
}

void eraseBall()
{
	drawbox(ballX, ballY, ballX+BALL_SIZE, ballY+BALL_SIZE, BLACK);
}

void updateBall()
{
    ballX += velX;
    ballY += velY;

    //did ball hit right wall?
    if (ballX > SCREEN_W - BALL_SIZE - 1)
    {
        velX *= -1;
        score1++;
    }

    //did ball hit left wall?
    if (ballX < 1)
    {
        velX *= -1;
        score2++;
    }

    //did ball hit top or bottom walls?
    if (ballY < 12 || ballY > SCREEN_H - BALL_SIZE - 1)
        velY *= -1;

}

void drawBall()
{
	drawbox(ballX, ballY, ballX+BALL_SIZE, ballY+BALL_SIZE, MAGENTA);
}

void erasePaddle1()
{
	drawbox(paddleX[1], paddleY[1], paddleX[1] + PADDLE_WIDTH, paddleY[1] + PADDLE_HEIGHT, BLACK);
}

void updatePaddle1()
{
    int py = paddleY[1] + PADDLE_HEIGHT/2;

    //only move computer paddle if ball is moving toward left
    if (velX < 0 && ballX < 120) {
        
        if (py > ballY) {
            paddleY[1] -= 1;
            if (paddleY[1] < 12) paddleY[1] = 12;
        }

        if (py < ballY) {
            paddleY[1] += 1;
            if (paddleY[1] > 160-PADDLE_HEIGHT)
                paddleY[1] = 160-PADDLE_HEIGHT;
        }
    }


}

void drawPaddle1()
{
	drawbox(paddleX[1], paddleY[1], paddleX[1] + PADDLE_WIDTH, paddleY[1] + PADDLE_HEIGHT, CYAN);
}

void erasePaddle2()
{
	drawbox(paddleX[2], paddleY[2], paddleX[2] + PADDLE_WIDTH, paddleY[2] + PADDLE_HEIGHT, BLACK);
}

void updatePaddle2()
{
    //check for UP button press
    if (buttonPressed(64))
    {
        if (paddleY[2] > 10)
            paddleY[2] -= PADDLE_SPEED;
    }
    
    //check for DOWN button press
    if (buttonPressed(128))
    {
        if (paddleY[2] < SCREEN_H - PADDLE_HEIGHT - 1)
            paddleY[2] += PADDLE_SPEED;
    }
}

void drawPaddle2()
{
	drawbox(paddleX[2], paddleY[2], paddleX[2] + PADDLE_WIDTH, paddleY[2] + PADDLE_HEIGHT, CYAN);
}

void checkCollisions()
{
    int x,y;
    
    //see if ball hit a paddle
    x = ballX + BALL_SIZE/2;
    y = ballY + BALL_SIZE/2;
    if (getpixel(x,y) != BLACK)
    {
        //we have a hit! 
        velX *= -1;
        ballX += velX;
    }
}

void waitRetrace()
{
	while (VCOUNT != 160);
	while (VCOUNT == 160);
}

int main(void)
{
    //init video mode 3 (240x160)
    setMode(VIDEO_MODE_3);
    
    //init the ball
    ballX = SCREEN_W / 2 - BALL_SIZE / 2;
    ballY = 40;
    
    //init the left paddle
    paddleX[1] = 10;
    paddleY[1] = SCREEN_H / 2 - PADDLE_HEIGHT / 2;
    
    //init the right paddle
    paddleX[2] = SCREEN_W - 20;
    paddleY[2] = SCREEN_H / 2 - PADDLE_HEIGHT / 2;

    //clear the screen
    drawbox(0, 0, 239, 159, BLACK);
    
    //display title
    print(120-16,1,"PONG",BLUE);


    //game loop
    while(1)
    {
        waitRetrace();
        
        eraseBall();
        erasePaddle1();
        erasePaddle2();

        updatePaddle1();
        updatePaddle2();
        updateBall();

        drawPaddle1();
        drawPaddle2();

        checkCollisions();
        drawBall();

        printScores();
    }

    return 0;
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -