分享
 
 
 

Mophun & J2ME 的游戏开发之旅(四)

王朝java/jsp·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

CASE STUDY:

MyMSnakeS3D:我的手机贪吃蛇游戏类3D版本

技巧:通过2D到3D的投影,画出类3D效果.

/////////////////////////////////////////////////////////////////////////////////////RES.TXT

#include <datacert.h>

INFO METAINFO

{

"Title" : "MyMSnakeS3D"

"Vendor" : "gowithfox@163.com"

"Copyright info" : "美元右括号"

"Program version" : "0.02"

"Help" : "Help me!"

}

// ***********************************************************************************************

// CERTIFICATION STUFF

// ***********************************************************************************************

DATACERT_AND_SECURITY_RESOURCE

CREDITS DATA { FILL 32,0}

SECTION DATA

// *****************************************

// THE FONT

// *****************************************

FONTA DATA "gfx/systemfont4x6.fnt"

TILES TILESET 8 8 FORMAT RGB332 "gfx/tiles.bmp"

MYSPRITE SPRITE FORMAT RGB332 "gfx/sprite.bmp"

MY_M_SNAKE_3D_TITLE SPRITE FORMAT RGB332 "gfx/title.bmp"

/////////////////////////////////////////////////////////////////////////////////////MyMSnake.mak

# *****************************************

#

# NAME: makefile

# PROJECT: MyMSnakeS3D我的移动贪吃蛇类3D

# DATE: 2004-10-09

# BY: Gaogao gowithfox@163.com

# version : 0.02

# 美元右括号

# +加入类3D 的图像模式

# *****************************************

# *****************************************

# FLAGS

# *****************************************

CFLAGS = -O2 -Wall -fvstudio

# *****************************************

# OBJEKTFILES

# *****************************************

OBJS = res.o MyMSnake.o

all: MyMSnake.mpn

# *****************************************

# RESOURCE

# *****************************************

res.o: res.txt

morc -v res.txt

# *****************************************

# COMPILER

# *****************************************

.c.o:

pip-gcc -c $(CFLAGS) -o $@ $<

# *****************************************

# LINKER

# *****************************************

MyMSnake.mpn: $(OBJS)

pip-gcc -o $@ $(OBJS) -mstack=1024 -mdata=10000 -ldatacert -s

/////////////////////////////////////////////////////////////////////////////////////MyMSnake.h

// *********************************************

// 贪吃蛇的Mophun版本for SE T618

// @author 美元右括号

// @version 0.02

// @connect gowithfox@163.com

// +加入类3D 的图像模式

// *********************************************

#ifndef MYMSNAKE_H

#define MYMSNAKE_H

#include <vmgp.h>

#include "res.h"

// *********************************************

// GLOBAL variables for MyMSnake GAME

// *********************************************

#define TRUE 1

#define FALSE 0

// 屏幕宽

int32_t screen_width = 0;

//BUG IN 0.01

//#define SCREEN_HEIGHT = 160;

#define SCREEN_WIDTH 128

// 屏幕高

int32_t screen_height = 0;

//BUG IN 0.01

//#define SCREEN_HEIGHT = 160;

#define SCREEN_HEIGHT 160

// 字体设置

VMGPFONT FontA;

// 蛇身体元素的大小

#define SNAKE_ELEMENT_SIZE 8

// 方向设置

#define UP_DIRECTION 0

#define DOWN_DIRECTION 1

#define LEFT_DIRECTION 2

#define RIGHT_DIRECTION 3

// 地图的初始状态

#define EMPTY 0

// 地图被Snake1个身体映射的状态

#define SNAKE_IN 1

// 地图被Snake2个身体映射的状态

#define SNAKE_OVERFLOW 2

// 蛇的身体的存储

typedef struct

{

struct SnakeElement * next;

int16_t x;

int16_t y;

int16_t direction;

}SnakeElement;

// Snake的头和尾指针

SnakeElement * snakeHead, * snakeTail;

// 蛇的食物的存储

typedef struct

{

int16_t x;

int16_t y;

int16_t var;

}SnakeFood;

// 食物是否被吃

int16_t isFoodBeEaten = FALSE;

// 可爱的贪吃蛇是不是因为贪吃而死亡?

int16_t isTheSnakeDead = FALSE;

// 地图的宽

#define X_MAX 16

// 地图的高

#define Y_MAX 20

// 地图存储

int16_t backgroundArray[Y_MAX][X_MAX];

//贪吃蛇的初始位置设定

#define X_INIT 8

#define Y_INIT 10

//游戏计数器

#define LEVEL_NUM 10

int16_t level_counter[] = {30, 25, 20, 18, 16, 13, 11, 10, 5, 3};

////////LEVEL_NUM

int16_t currentLevel = 0;

int16_t counter = 0;

//食物的初始位置

SnakeFood snakeFood;

#define FRAME_CONTROLER 30

// 方法

void initGame(void);

// 初始化屏幕

void GetScreenSize(void);

// 初始化字体

void InitFont(void);

// 地图初始化

void initMap(void);

// 贪吃蛇初始化

void initSnake(void);

// 移动贪吃蛇

void moveSnake(void);

// 生成食物

void generateFood(void);

// 绘制游戏场景

void paintObjects(void);

// 销毁一切游戏中的内存碎片

void destroyObjects(void);

// S3D效果

// S3D坐标获得

int16_t getS3DX(int16_t x, int16_t y);

int16_t getS3DY(int16_t y);

#endif

/////////////////////////////////////////////////////////////////////////////////////MyMSnake.c

// *********************************************

// 贪吃蛇的Mophun版本for SE T618

// @author 美元右括号

// @version 0.02

// @connect gowithfox@163.com

// 加入类3D 的图像模式

// *********************************************

#include "MyMSnake.h"

void initGame(void)

{

isTheSnakeDead = FALSE;

isFoodBeEaten = FALSE;

currentLevel = 0;

counter = 0;

}

// *******************************************************

// 获得屏幕尺寸

// *******************************************************

void GetScreenSize(void)

{

VIDEOCAPS videocaps;

videocaps.size = sizeof(VIDEOCAPS);

if(vGetCaps(CAPS_VIDEO,&videocaps))

{

screen_width = videocaps.width;

screen_height = videocaps.height;

}

}

// *******************************************************

// 新建字体

// *******************************************************

void InitFont(void)

{

FontA.width = 4;

FontA.height = 6;

FontA.bpp = 1;

FontA.palindex = 0;

FontA.chartbl = FONTA + 16;

FontA.fontdata = FONTA + 16 + 256;

vSetActiveFont(&FontA);

}

// 地图初始化

void initMap(void)

{

int i = 0, j = 0;

for (i = 0; i < Y_MAX; i++)

{

for (j = 0; j < X_MAX; j++)

{

backgroundArray[i][j] = EMPTY;

}

}

}

// 贪吃蛇初始化

void initSnake(void)

{

SnakeElement *temp;

snakeTail = (SnakeElement *)malloc(sizeof(SnakeElement));

snakeTail->x = X_INIT - 3;

snakeTail->y = Y_INIT;

snakeTail->direction = RIGHT_DIRECTION;

snakeTail->next = (SnakeElement *)malloc(sizeof(SnakeElement));

temp = snakeTail->next;

temp->x = X_INIT - 2;

temp->y = Y_INIT;

temp->direction = RIGHT_DIRECTION;

temp->next = (SnakeElement *)malloc(sizeof(SnakeElement));

temp = temp->next;

temp->x = X_INIT - 1;

temp->y = Y_INIT;

temp->direction = RIGHT_DIRECTION;

temp->next = (SnakeElement *)malloc(sizeof(SnakeElement));

temp = temp->next;

temp->x = X_INIT;

temp->y = Y_INIT;

temp->direction = RIGHT_DIRECTION;

temp->next = NULL;

snakeHead = temp;

backgroundArray[Y_INIT][ X_INIT - 3] = SNAKE_IN;

backgroundArray[Y_INIT][ X_INIT - 2] = SNAKE_IN;

backgroundArray[Y_INIT][ X_INIT - 1] = SNAKE_IN;

backgroundArray[Y_INIT][ X_INIT - 0] = SNAKE_IN;

}

// 移动贪吃蛇

void moveSnake(void)

{

//清理不backgroundArray;

SnakeElement * temp = snakeTail;

while (temp!=NULL)

{

backgroundArray[temp->y][temp->x] = EMPTY;

temp = temp->next;

}

//移动Snake

SnakeElement * tempTailToo = (SnakeElement *)malloc(sizeof(SnakeElement));

tempTailToo->x = snakeTail->x;

tempTailToo->y = snakeTail->y;

tempTailToo->direction = snakeTail->direction;

SnakeElement * tempNewHead = snakeTail;

snakeTail = snakeTail->next;

tempNewHead->next = NULL;

switch (snakeHead->direction)

{

case UP_DIRECTION:

tempNewHead->y = snakeHead->y - 1;

tempNewHead->x = snakeHead->x;

tempNewHead->direction = snakeHead->direction;

break;

case DOWN_DIRECTION:

tempNewHead->y = snakeHead->y + 1;

tempNewHead->x = snakeHead->x;

tempNewHead->direction = snakeHead->direction;

break;

case LEFT_DIRECTION:

tempNewHead->x = snakeHead->x - 1;

tempNewHead->y = snakeHead->y;

tempNewHead->direction = snakeHead->direction;

break;

case RIGHT_DIRECTION:

tempNewHead->x = snakeHead->x + 1;

tempNewHead->y = snakeHead->y;

tempNewHead->direction = snakeHead->direction;

break;

}

snakeHead->next = tempNewHead;

snakeHead = snakeHead->next;

if (snakeHead->x == snakeFood.x

&&

snakeHead->y == snakeFood.y

)

{

isFoodBeEaten = TRUE;

}

if (isFoodBeEaten == TRUE)

{

//isFoodBeEaten = FALSE;

tempTailToo->next = snakeTail;

snakeTail = tempTailToo;

generateFood();

}

//移动后

temp = snakeTail;

while (temp!=NULL)

{

backgroundArray[temp->y][temp->x] += SNAKE_IN;

if (backgroundArray[temp->y][temp->x] > SNAKE_IN)

{

isTheSnakeDead = TRUE;

}

temp = temp->next;

}

if (snakeHead->x < 0 ||

snakeHead->y < 0 ||

snakeHead->x >= X_MAX ||

snakeHead->y >= Y_MAX)

{

isTheSnakeDead = TRUE;

}

}

// 生成食物

void generateFood(void)

{

if (isFoodBeEaten == FALSE)

{

return;

}

else

{

int x;

int y;

vSetRandom(vGetTime());

x = abs(vGetRandom() % X_MAX);

vSetRandom(vGetTime());

y = abs(vGetRandom() % Y_MAX);

if (backgroundArray[y][x] == EMPTY)

{

snakeFood.x = x;

snakeFood.y = y;

snakeFood.var = 1;

isFoodBeEaten = FALSE;

}

generateFood();

}

}

// 绘制游戏场景

void paintObjects(void)

{

SnakeElement *temp = snakeTail;

// ---- Init Graphics --------------------------------

vSetClipWindow(0,0,screen_width,screen_height); // Set Maximum Clipwindow

vSetForeColor(vRGB(255,255,255)); // White forecolor

vSetBackColor(vRGB(0,0,0)); // Black background

vClearScreen(vRGB(0,0,0)); // Fill Screen with black

vSetTransferMode(MODE_TRANS); // Set transfer mode to transparent

// 以下在新版本中被屏蔽

// while (temp!=NULL)

// {

// vDrawObject (temp->x * SNAKE_ELEMENT_SIZE, temp->y * SNAKE_ELEMENT_SIZE, &MYSPRITE);

// temp = temp->next;

// }

// vDrawObject (snakeFood.x * SNAKE_ELEMENT_SIZE, snakeFood.y * SNAKE_ELEMENT_SIZE, &MYSPRITE);

// 在新版本中被屏蔽完毕

// while (temp!=NULL)

// {

// vDrawObject (temp->x * SNAKE_ELEMENT_SIZE, temp->y * SNAKE_ELEMENT_SIZE, &MYSPRITE);

// temp = temp->next;

// }

// vDrawObject (snakeFood.x * SNAKE_ELEMENT_SIZE, snakeFood.y * SNAKE_ELEMENT_SIZE, &MYSPRITE);

// S3D

vSetForeColor(vRGB(0,255,0));

vDrawLine(X_MAX * SNAKE_ELEMENT_SIZE / 4 , Y_MAX * SNAKE_ELEMENT_SIZE / 2, 0, Y_MAX * SNAKE_ELEMENT_SIZE );

vDrawLine(X_MAX * SNAKE_ELEMENT_SIZE / 4, Y_MAX * SNAKE_ELEMENT_SIZE / 2, X_MAX * SNAKE_ELEMENT_SIZE / 4, 0);

vDrawLine(3 * X_MAX * SNAKE_ELEMENT_SIZE / 4, Y_MAX * SNAKE_ELEMENT_SIZE / 2, X_MAX * SNAKE_ELEMENT_SIZE , Y_MAX * SNAKE_ELEMENT_SIZE );

vDrawLine(3 * X_MAX * SNAKE_ELEMENT_SIZE / 4, Y_MAX * SNAKE_ELEMENT_SIZE / 2, 3 * X_MAX * SNAKE_ELEMENT_SIZE / 4, 0);

vDrawLine(1 * X_MAX * SNAKE_ELEMENT_SIZE / 4, Y_MAX * SNAKE_ELEMENT_SIZE / 2, 3 * X_MAX * SNAKE_ELEMENT_SIZE / 4, Y_MAX * SNAKE_ELEMENT_SIZE / 2);

// S3DEND

vSetForeColor(vRGB(255, 255, 255));

while (temp != NULL)

{

int16_t x_0 = temp->x;

int16_t x_1 = temp->x + 1;

int16_t y_0 = temp->y;

int16_t y_1 = temp->y + 1;

// 首先把坐标分成标准坐标

// 2D Test

//x_0 = (X_MAX / 2) * SNAKE_ELEMENT_SIZE + x_0 * SNAKE_ELEMENT_SIZE;

//x_1 = (X_MAX / 2) * SNAKE_ELEMENT_SIZE + x_1 * SNAKE_ELEMENT_SIZE;

//vDrawLine(x_0, y_0, x_1, y_0);

//vDrawLine(x_0, y_0, x_0, y_1);

//vDrawLine(x_0, y_1, x_1, y_1);

//vDrawLine(x_1, y_0, x_1, y_1);

// 2D TestEND

// S3D

int16_t x_left_top = getS3DX(x_0, y_0);

int16_t x_right_top = getS3DX(x_1, y_0);

int16_t x_left_bottom = getS3DX(x_0, y_1);

int16_t x_right_bottom = getS3DX(x_1, y_1);

int16_t y_3D_0 = getS3DY(y_0);

int16_t y_3D_1 = getS3DY(y_1);

vDrawLine(x_left_top, y_3D_0, x_right_top, y_3D_0);

vDrawLine(x_left_top,y_3D_0, x_left_bottom, y_3D_1);

vDrawLine(x_left_bottom, y_3D_1, x_right_bottom, y_3D_1);

vDrawLine(x_right_top, y_3D_0, x_right_bottom, y_3D_1);

// S3D END

//坐标变换

temp = temp->next;

}

// S3D FOOD

int16_t x_0 = snakeFood.x;

int16_t x_1 = snakeFood.x + 1;

int16_t y_0 = snakeFood.y;

int16_t y_1 = snakeFood.y + 1;

int16_t x_left_top = getS3DX(x_0, y_0);

int16_t x_right_top = getS3DX(x_1, y_0);

int16_t x_left_bottom = getS3DX(x_0, y_1);

int16_t x_right_bottom = getS3DX(x_1, y_1);

int16_t y_3D_0 = getS3DY(y_0);

int16_t y_3D_1 = getS3DY(y_1);

vSetForeColor(vRGB(255,255,0));

vDrawLine(x_left_top, y_3D_0, x_right_top, y_3D_0);

vDrawLine(x_left_top,y_3D_0, x_left_bottom, y_3D_1);

vDrawLine(x_left_bottom, y_3D_1, x_right_bottom, y_3D_1);

vDrawLine(x_right_top, y_3D_0, x_right_bottom, y_3D_1);

// S3D FOOD END

// 3D Backgound

vDrawObject(1 * X_MAX * SNAKE_ELEMENT_SIZE / 4, 0, &MY_M_SNAKE_3D_TITLE);

// 3D Backgound END

vFlipScreen(1);

}

// 销毁一切游戏中的内存碎片

void destroyObjects(void)

{

///////////////////////////////////////

}

int main(void)

{

initGame();

InitFont();

GetScreenSize();

initMap();

initSnake();

uint32_t frame;

int16_t currentDirection = snakeHead->direction;

while (1)

{

switch(vGetButtonData())

{

case KEY_UP:

if (currentDirection != DOWN_DIRECTION)

{

snakeHead->direction = UP_DIRECTION;

}

break;

case KEY_DOWN:

if (currentDirection != UP_DIRECTION)

{

snakeHead->direction = DOWN_DIRECTION;

}

break;

case KEY_LEFT:

if (currentDirection != RIGHT_DIRECTION)

{

snakeHead->direction = LEFT_DIRECTION;

}

break;

case KEY_RIGHT:

if (currentDirection != LEFT_DIRECTION)

{

snakeHead->direction = RIGHT_DIRECTION;

}

break;

}

frame = vGetTickCount();

if (counter++ > level_counter[currentLevel])

{

counter = 0;

if (isTheSnakeDead != TRUE){

moveSnake();

currentDirection = snakeHead->direction;

}

}

paintObjects();

while (vGetTickCount() - frame < FRAME_CONTROLER);

}

return 0;

}

// 获得类3D的x坐标

int16_t getS3DX(int16_t x, int16_t y)

{

int16_t result =

(SNAKE_ELEMENT_SIZE * (X_MAX / 2))

+

((x - (X_MAX / 2)) * SNAKE_ELEMENT_SIZE * ((Y_MAX + y) / 2) * SNAKE_ELEMENT_SIZE) /

(Y_MAX * SNAKE_ELEMENT_SIZE);

return result;

}

// 获得类3D的y坐标

int16_t getS3DY(int16_t y)

{

return ((Y_MAX + y) * SNAKE_ELEMENT_SIZE) / 2;

}

图片展示:

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有