知识共享-Android版贪吃蛇源码及分析(雷惊风)
- 格式:doc
- 大小:306.00 KB
- 文档页数:10
Android ---snake源代码分析代码结构分析:Snake :主游戏窗口SnakeView :游戏视图类,是实现游戏的主体类TileView :一个处理图片或其它Coordinate :这是一个包括两个参数,用于记录X轴和Y轴简单类,其中包括一个比较函数.RefshHandler :用于更新视图Snake这个类是游戏的主游戏窗口,是框架容器,1.游戏的开始:oncreate此外的亮点是:setContentView(yout.snake_layout);设置窗口的布局文件,这里Android123给大家说明的是,这里的snake_layout使用了自定义资源标签的方式,大家注意学习:这里我们可以看到来自SnakeView这个派生类的名称,由于Android内部的R.资源不包含SnakeView类,所以我们必须写清楚Package,比如com.exmple.android.snake.SnakeView 然后和其他控件使用一样,都是一个id然后宽度、高度、以及自定义的标签tileSize(尾巴长度),如下:<com.example.android.snake.SnakeViewandroid:id="@+id/snake"android:layout_width="fill_parent"android:layout_height="fill_parent"tileSize="12"/>2.onPause:关于这点,大家可以参考下在我blog中关于active生命周期/admin/blogs/379826在玩游戏过程中,如果有来电或是其它事件中断,这时应该把当前状态保存。
以便返回时,还可以继续玩游戏。
这就使用onSaveInstanceState实现保存当前状态。
TileView注:此部分解析来自: Android示例程序Snake贪食蛇代码分析(三)TileView,从名称上不难看出这是一个方砖类,就是生成一个方块。
超简单贪吃蛇c语言代码编写贪吃蛇其实就是实现以下几步——1:蛇的运动(通过“画头擦尾”来达到蛇移动的视觉效果)2:生成食物3:蛇吃食物(实现“画头不擦尾”)4:游戏结束判断(也就是蛇除了食物,其余东西都不能碰)#include<stdio.h>#include<stdlib.h>#include<windows.h>#include<conio.h>#include<time.h>#define width 60#define hight 25#define SNAKESIZE 200//蛇身的最长长度int key=72;//初始化蛇的运动方向,向上int changeflag=1;//用来标识是否生成食物,1表示蛇还没吃到食物,0表示吃到食物int speed=0;//时间延迟struct {int len;//用来记录蛇身每个方块的坐标int x[SNAKESIZE];int y[SNAKESIZE];int speed;}snake;struct{int x;int y;}food;void gotoxy(int x,int y)//调用Windows的API函数,可以在控制台的指定位置直接操作,这里可暂时不用深究{COORD coord;coord.X = x;coord.Y = y;SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); }//■○void drawmap(){//打印图框for (int _y = 0; _y < hight; _y++){for (int x = 0; x < width; x+=2){if (x == 0 || _y == 0 || _y == hight - 1 || x == width - 2){gotoxy(x, _y);printf("■");}}}//打印蛇头snake.len=3;snake.x[0]=width/2;snake.y[0]=hight/2;gotoxy(snake.x[0],snake.y[0]);printf("■");//打印蛇身for(int i=1;i<snake.len;i++){snake.x[i]=snake.x[i-1];snake.y[i]=snake.y[i-1]+1;gotoxy(snake.x[i],snake.y[i]);printf("■");}//初始化食物的位置food.x=20;food.y=20;gotoxy(food.x,food.y);printf("○");}/**控制台按键所代表的数字*“↑”:72*“↓”:80*“←”:75*“→”:77*/void snake_move()//按键处理函数{int history_key=key;if (_kbhit()){fflush(stdin);key = _getch();key = _getch();}if(changeflag==1)//还没吃到食物,把尾巴擦掉{gotoxy(snake.x[snake.len-1],snake.y[snake.len-1]);printf(" ");}for(int i=snake.len-1;i>0;i--){snake.x[i]=snake.x[i-1];snake.y[i]=snake.y[i-1];}if(history_key==72&&key==80)key=72;if(history_key==80&&key==72)key=80;if(history_key==75&&key==77)key=75;if(history_key==77&&key==75)key=77;switch(key){case 72:snake.y[0]--;break;case 75:snake.x[0]-= 2;break;case 77:snake.x[0]+= 2;break;case 80:snake.y[0]++;break;}gotoxy(snake.x[0],snake.y[0]);printf("■");gotoxy(0,0);changeflag=1;}void creatfood(){if(snake.x[0] == food.x && snake.y[0] == food.y)//只有蛇吃到食物,才能生成新食物{changeflag=0;snake.len++;if(speed<=100)speed+=10;while(1){srand((unsigned int) time(NULL));food.x=rand()%(width-6)+2;//限定食物的x范围不超出围墙,但不能保证food.x 为偶数food.y=rand()%(hight-2)+1;for(int i=0;i<snake.len;i++){if(food.x==snake.x[i]&&food.y==snake.y[i])//如果产生的食物与蛇身重合则退出break;}if(food.x%2==0)break;//符合要求,退出循环}gotoxy(food.x,food.y);printf("○");}}bool Gameover(){//碰到围墙,OVERif(snake.x[0]==0||snake.x[0]==width-2)return false;if(snake.y[0]==0||snake.y[0]==hight-1) return false;//蛇身达到最长,被迫OVERif(snake.len==SNAKESIZE)return false;//头碰到蛇身,OVERfor(int i=1;i<snake.len;i++){if(snake.x[0]==snake.x[i]&&snake.y[0]==snake.y[i])return false;}return true;}int main(){system("mode con cols=60 lines=27");drawmap();while(Gameover()){snake_move();creatfood();Sleep(350-speed);//蛇的移动速度}return 0;}。
贪吃蛇游戏实现思路及源代码HTML5 贪吃蛇游戏实现思路及源代码点评:游戏难点是怎么模拟贪吃蛇的移动。
如果只是一个方块的话显然很简单。
但是当蛇的长度变长之后要怎么样控制,下面为大家简要介绍下具体的实现,感兴趣的朋友可以参考下,希望对大家有所帮助游戏操作说明通过方向键控制贪吃蛇上下左右移动。
贪吃蛇吃到食物之后会变长一个长度。
游戏具体实现游戏难点是怎么模拟贪吃蛇的移动。
如果只是一个方块的话显然很简单。
但是当蛇的长度变长之后要怎么样控制每个方块的移动呢?如果观察蛇的移动,可以发现,从蛇的头部到尾部,每个方块在下一时刻的位置就是它的前一个方块在当前时刻的位置。
因此我们需要做的只是控制贪吃蛇的头部的运动。
其他部分的位置都可以依次类推。
另外一个值得注意的问题是贪吃蛇吃下食物之后,新增加的方块应该放在哪个位置。
答案就是在下一时刻,新增加的方块应该出现在当前时刻的尾部位置。
因此,在吃下食物之后应该在更新蛇的每个位置之前,增加一个方块,并且将其位置设定在当前时刻的尾部位置。
然后在当前时刻更新出了新增方块之外的所有方块的位置index.htmlsnake.js复制代码代码如下:var canvas;var ctx;var timer;//measuresvar x_cnt = 15;var y_cnt = 15;var unit = 48;var box_x = 0;var box_y = 0;var box_width = 15 * unit;var box_height = 15 * unit;var bound_left = box_x;var bound_right = box_x + box_width;var bound_up = box_y;var bound_down = box_y + box_height;//imagesvar image_sprite;//objectsvar snake;var food;var food_x;var food_y;//functionsfunction Role(sx, sy, sw, sh, direction, status, speed, image, flag) {this.x = sx;this.y = sy;this.w = sw;this.h = sh;this.direction = direction;this.status = status;this.speed = speed;this.image = image;this.flag = flag;}function transfer(keyCode){switch (keyCode){case 37:return 1;case 38:return 3;case 39:return 2;case 40:return 0;}}function addFood(){//food_x=box_x+Math.floor(Math.random()*(box_width-unit));//food_y=box_y+Math.floor(Math.random()*(box_height-unit));food_x = unit * Math.floor(Math.random() * x_cnt);food_y = unit * Math.floor(Math.random() * y_cnt);food = new Role(food_x, food_y, unit, unit, 0, 0, 0, image_sprite, true);}function play(event){var keyCode;if (event == null){keyCode = window.event.keyCode;window.event.preventDefault();}else{keyCode = event.keyCode;event.preventDefault();}var cur_direction = transfer(keyCode);snake[0].direction = cur_direction;}function update(){//add a new part to the snake before move the snakeif (snake[0].x == food.x && snake[0].y == food.y){var length = snake.length;var tail_x = snake[length - 1].x;var tail_y = snake[length - 1].y;var tail = new Role(tail_x, tail_y, unit, unit, snake[length - 1].direction, 0, 0, image_sprite, true); snake.push(tail);addFood();}//modify attributes//move the headswitch (snake[0].direction){case 0: //downsnake[0].y += unit;if (snake[0].y > bound_down - unit) snake[0].y = bound_down - unit; break;case 1: //leftsnake[0].x -= unit;if (snake[0].x < bound_left)snake[0].x = bound_left;break;case 2: //rightsnake[0].x += unit;if (snake[0].x > bound_right - unit) snake[0].x = bound_right - unit; break;case 3: //upsnake[0].y -= unit;if (snake[0].y < bound_up)snake[0].y = bound_up;break;}//move other part of the snakefor (var i = snake.length - 1; i >= 0; i--) {if (i > 0)//snake[i].direction=snake[i-1].direction; {snake[i].x = snake[i - 1].x;snake[i].y = snake[i - 1].y;}}}function drawScene(){ctx.clearRect(box_x, box_y, box_width, box_height); ctx.strokeStyle = "rgb(0,0,0";ctx.strokeRect(box_x, box_y, box_width, box_height); //detection collisions//draw imagesfor (var i = 0; i < snake.length; i++){ctx.drawImage(image_sprite, snake[i].x, snake[i].y); }ctx.drawImage(image_sprite, food.x, food.y);}function init(){canvas = document.getElementById("scene");ctx = canvas.getContext('2d');//imagesimage_sprite = new Image();image_sprite.src = "images/sprite.png";image_sprite.onLoad = function (){}//ojectssnake = new Array();var head = new Role(0 * unit, 0 * unit, unit, unit, 5, 0, 1, image_sprite, true); snake.push(head);window.addEventListener('keydown', play, false);addFood();setInterval(update, 300); //notesetInterval(drawScene, 30); }。
安卓贪吃蛇源代码#define M 200#include"graphics.h"#include<stdlib.h>#include<stdio.h>#include<string.h>#include<iostream.h>#include<dos.h>#include<conio.h>#include <windows.h>#define LEFT 97//A#define RIGHT 100//D#define DOWN 115//S#define UP 119//W#define Esc 0x011bint i,key;int score=0;int gamespeed=250;//游戏速度可根据实际情况自行调整struct Food{int x;//食物的横坐标int y;//食物的纵坐标int yes;//判断是否要出现食物的变量}food;//食物的结构体struct Snake{int x[M];int y[M];int node;//蛇的节数int direction;//蛇的移动方向int life;//蛇的生命,0表示活着,1表示死亡}snake;void Init();//图形驱动void Close();//图形结束void DrawK();//开始画面void GamePlay();//玩游戏的具体过程void GameOver();//游戏结束void PrScore();//输出成绩void main()//主函数{Init();//图形驱动DrawK();//开始画面GamePlay();//玩游戏的具体过程Close();//图形结束}void Init()//图形驱动{int gd=DETECT,gm;initgraph(&gd,&gm," ");/*此处为turboc的路径,读者可以根据自己的电脑而改*/cleardevice();}void DrawK()//开始画面,左上角坐标为(50,40),右下角坐标为(610,460)的围墙{setbkcolor(GREEN);setcolor(LIGHTRED);setlinestyle(0,0,5);//设置线型for(i=50;i<=600;i+=10)//画围墙{rectangle(i,40,i+10,49);//上边rectangle(i,451,i+10,460);//下边}for(i=40;i<=450;i+=10){rectangle(50,i,59,i+10);//左边rectangle(601,i,610,i+10);//右边}}void GamePlay()//玩游戏的具体过程{rand();//随机数发生器food.yes=1;//1表示需要出现新食物,0表示已经存在食物snake.life=0;//蛇活着snake.direction=1;//方向往右snake.x[0]=100;snake.y[0]=100;//舌头坐标snake.x[1]=110;snake.y[1]=100 ;snake.node=2;//蛇的节数PrScore();//输出分数while(1)//可重复玩游戏,按ESC键结束{while(!kbhit())//在没有按键的情况下,蛇自己移动身体{if(food.yes==1)//需要出现新食物{food.x=rand()%400+60;food.y=rand()%350+60;while(food.x%10!=0)//食物随即出现后必须让食物能够在整格内,这样才能让蛇迟到food.x++;while(food.y%10!=0)food.y++;food.yes=0;//画面上有食物了}if(food.yes==0)//画面上有食物就要显示{setcolor(GREEN);rectangle(food.x,food.y,food.x+10,food.y-10);}for(i=snake.node-1;i>0;i--)//蛇的每个环节往前移动,也就是贪吃蛇的关键算法{snake.x[i]=snake.x[i-1];snake.y[i]=snake.y[i-1];}switch(snake.direction)//1,2,3,4表示上下左右四个方向,通过这个判断来移动蛇头{case 1:snake.x[0]+=10;break;case 2:snake.x[0]-=10;break;case 3:snake.y[0]-=10;break;case 4:snake.y[0]+=10;break;}for(i=3;i<snake.node;i++)//从蛇的第四节开始判断是否撞到自己了,因为蛇头为两节,第三节不可能拐过来{if(snake.x[i]==snake.x[0]&&snake.y[i]==snake.y[0]){GameOver();//显示失败snake.life=1;break;}}if(snake.x[0]<55||snake.x[0]>595||snake.y[0]<55||snake.y[0]>455)//蛇是否撞到墙壁{GameOver();//本次游戏结束snake.life=1;//蛇死}if(snake.life==1)//以上两种判断以后,如果蛇死就跳出内循环,重新开始break;if(snake.x[0]==food.x&&snake.y[0]==food.y)//吃到食物以后{setcolor(0);//把画面上的食物去掉rectangle(food.x,food.y,food.x+10,food.y-10);snake.x[snake.node]=-20;snake.y[snake.node]=-20;//新的一节先放在看不见得位置,下次循环就取前一节的位置snake.node++;//蛇的身体长一节food.yes=1;score+=10;PrScore();//输出新的得分}setcolor(WHITE);//画出蛇for(i=0;i<snake.node;i++)rectangle(snake.x[i],snake.y[i],snake.x[i]+10,snake.y[i]-10);Sleep(gamespeed);setcolor(0);//用黑色去除蛇的最后一节rectangle(snake.x[snake.node-1],snake.y[snake.node-1],snake.x[snake.node-1]+10,snake.y[snake.node-1]-10);}if(snake.life==1)//如果蛇死就跳出循环break;key=getchar();//接受案件if(key==Esc)//按ESC键退出break;else if(key==UP&&snake.direction!=4)snake.direction=3;else if(key==RIGHT&&snake.direction!=2)snake.direction=1;else if(key==LEFT&&snake.direction!=1)snake.direction=2;else if(key==DOWN&&snake.direction!=3)snake.direction=4;}//endwhile(1)}void GameOver()//游戏结束{cleardevice();PrScore();setcolor(RED);outtextxy(100,100,"我会回来的!!!!!");getch();}void PrScore()//输出成绩{char str[10];setfillstyle(SOLID_FILL,YELLOW);bar(50,15,220,35);setcolor(6);sprintf(str,"score:%d",score);outtextxy(55,20,str);}void Close()//图形结束{getch();closegraph();}。
DATA SEGMENTdw 0,0snk db 1blk db 32food db 3tal1 db 4tal2 db 2adrs db 5len db ?pst db ?addrs dw ?frow db ?fcol db ?hwrt db ?gmov db 'game over press r to restart press q to quit $'score1 db 'score :$'score2 db ?score0 db 1zero db 48writer db 'Developer: Geniusdot $'email db ': geniusdotgmail.$'msg1 db 'The way to play the game:$'way db ' press w to up ,press s to down,press a to left,press d to right$' msg db 'Press any key(except a,s,d,w) to start$'DATA ENDSSTACK SEGMENT stackdb 200 dup(0)STACK ENDSCODE SEGMENTASSUME CS:CODE,DS:DATA,SS:STACKstart:mov ax,datamov ds,axmov ax,0mov es,axmov frow,10mov fcol,6mov dh,10mov dl,26mov ah,2int 10hmov ah,9lea dx,msg1 int 21hmov dh,11 mov dl,7 mov ah,2 mov bh,0int 10hmov ah,9lea dx,way int 21hmov dh,12 mov dl,20 mov ah,2 mov bh,0int 10hmov ah,9lea dx,msg int 21hmov ah,0int 16hmov ah,6 mov al,0 mov ch,0 mov cl,0 mov dh,24 mov dl,79 mov bh,10 int 10hmov dh,0 mov dl,0 mov ah,2 mov bh,0int 10hmov ah,9lea dx,score1 int 21hmov dl,15 mov ah,2 mov bh,0int 10hlea dx,writerint 21hmov ah,9lea dx,emailint 21hmov score2,48push es:[9*4] ;将原int9入口地址保存pop ds:[0]push es:[9*4+2]pop ds:[2]mov word ptr es:[9*4],offset int9 ;更改中断向量表mov es:[9*4+2],csjmp aawrite macro row,col,cnt ;宏定义用于向当前光标处输出字符push bxpush cxpush dxmov dh,rowmov dl,colmov ah,2mov bh,0int 10hmov ah,9mov bl,11mov cx,1lea di,cnt ;50mov al,[di]int 10hpop dxpop cxpop bxendmreadh macro row,col ;宏定义用于读出当前光标处字符push dxpush bxmov dh,rowmov dl,colmov ah,2mov bh,0int 10hmov ah,08hint 10hmov pst,alpop bxpop axpop dxendmwnear macro ;宏定义只用在readcg宏中当readcg的所有判断都不成立调用此宏local wnext1local wnext2local wnext3local wnext4push dxdec dhreadh dh,dlcmp pst,1jne wnext1write dh,dl,tal2jmp wnext4wnext1:inc dhdec dlreadh dh,dlcmp pst,1jne wnext2write dh,dl,tal2jmp wnext4wnext2:inc dhinc dlreadh dh,dlcmp pst,1jne wnext3write dh,dl,tal2jmp wnext4dec dhinc dlreadh dh,dlcmp pst,1jne wnext4write dh,dl,tal2wnext4:pop dxendmreadcg macro row,col ;宏定义用于改变判断出来的字符local tnup,tnup1,tnup2,tnlf,tnlf1,tnlf2,tndn,tndn1,tndn2,tnrt,tnrt1,tnrt2,gooutpush bxpush axpush dxwrite dh,dl,tal1dec rowreadh dh,dlcmp pst,4jne tnup1jmp tnup2tnup1:jmp near ptr tnuptnup2:write dh,dl,blkinc dhinc dhreadh dh,dlcmp pst,1jne tnupwrite dh,dl,tal2jmp near ptr goouttnup:pop dxpush dxdec colreadh dh,dlcmp pst,4jne tnlf1jmp tnlf2tnlf1:jmp near ptr tnlf tnlf2:write dh,dl,blkinc dlinc dlreadh dh,dlcmp pst,1jne tnlfwrite dh,dl,tal2 jmp near ptr goout tnlf:pop dxpush dxinc rowreadh dh,dlcmp pst,4jne tndn1jmp tndn2tndn1:jmp near ptr tndn tndn2:write dh,dl,blk dec dhdec dhreadh dh,dlcmp pst,1jne tndnwrite dh,dl,tal2 jmp near ptr goout tndn:pop dxpush dxinc colreadh dh,dlcmp pst,4jne tnrt1jmp tnrt2tnrt1:jmp near ptr tnrt tnrt2:write dh,dl,blk dec dldec dlreadh dh,dlcmp pst,1jne tnrtwrite dh,dl,tal2jmp near ptr goouttnrt:pop dxpush dxwneargoout:pop dxpop axpop bxendmaddone: ;此标号功能是将蛇身增加一push dxinc score2mov dh,1mov dl,0mov cx,23cmpad1:push cxmov cx,79cmpad2:readh dh,dlcmp pst,2jne nextad3jmp nextad4nextad3:jmp near ptr nextadnextad4:write dh,dl,snkdec dhreadh dh,dlcmp pst,4jne natupwrite dh,dl,tal2dec dhwrite dh,dl,tal1jmp outonatup:inc dhreadh dh,dlcmp pst,4jne natlfwrite dh,dl,tal2dec dlwrite dh,dl,tal1jmp outonatlf:inc dhinc dlreadh dh,dlcmp pst,4jne natdnwrite dh,dl,tal2inc dhwrite dh,dl,tal1jmp outonatdn:dec dhinc dlreadh dh,dlcmp pst,4jne natrtwrite dh,dl,tal2inc dlwrite dh,dl,tal1 natrt:outo:pop cxjmp near ptr endad nextad:inc dljmp nextad2chgad2:jmp near ptr cmpad2 nextad2:loop chgad2sub dl,79inc dhpop cxjmp nextad1chgad1:jmp near ptr cmpad1loop chgad1endad:pop dxjmp near ptr crtfaa: ;从这开始产生最原始的蛇mov addrs,offset turnrightmov dh,10mov dl,1mov cx,3write dh,dl,tal1inc dlwrite dh,dl,tal2wrt:inc dlwrite dh,dl,snkloop wrtmov len,6mov ax,0jmp wrt1ovflw: ;当蛇碰壁或自身转到此游戏结束mov ah,6mov al,0mov ch,0mov cl,0mov dh,24mov dl,79mov bh,7int 10hmov dh,17mov dl,17mov ah,2mov bh,0int 10hmov ah,9lea dx,gmovint 21hmov ax,0 ;恢复int9中断mov es,axpop es:[9*4]push ds:[2]pop es:[9*4+2]stop:mov ah,0int 16hcmp al,'r'je aa1jmp aa2aa1:jmp near ptr startaa2:cmp al,'q'jne stopjmp near ptr exitwrt1: ;此处蛇行走过程的无限循环call dlypush dxinc dhcmp dh,25je ovflwinc dlcmp dl,80je ovflwpop dxpush dxdec dhcmp dh,0je ovflwdec dlcmp dl,-1je ovflwpop dxpush dxlea ax,turnrightcmp addrs,axjne tonxt2inc dlreadh dh,dlcmp pst,1je tonxt1cmp pst,2je tonxt1cmp pst,4je tonxt1jmp tonxt2 tonxt1:jmp ovflw tonxt2:pop dxpush dxlea ax,turnup cmp addrs,ax jne tonxt4dec dhreadh dh,dl cmp pst,1je tonxt3cmp pst,2je tonxt3cmp pst,4je tonxt3jmp tonxt4 tonxt3:jmp ovflw tonxt4:pop dxpush dxlea ax,turndown cmp addrs,ax jne tonxt6inc dhreadh dh,dl cmp pst,1je tonxt5cmp pst,2je tonxt5cmp pst,4je tonxt5jmp tonxt6 tonxt5:jmp ovflw tonxt6:pop dxpush dxlea ax,turnback cmp addrs,axjne tonxt8dec dlreadh dh,dlcmp pst,1je tonxt7cmp pst,2je tonxt7cmp pst,4je tonxt7jmp tonxt8tonxt7:jmp ovflwtonxt8:pop dxjmp nextacrtf1:jmp near ptr addone crtf:call rand1call rand2inc frowmov ah,frowmov al,fcolpush dxmov dh,1mov dl,0push cxmov cx,23check1:push cxmov cx,79check2:readh dh,dlcmp pst,1je nextncmp pst,2je nextncmp pst,4je nextnjmp nextnn nextn:cmp ax,dxje crtfnextnn:inc dlloop check2inc dhsub dl,79pop cxloop check1pop cxpop dxwrite frow,fcol,food nexta:mov ah,frowmov al,fcolcmp ax,dxje crtf12jmp crtf13crtf12:jmp near ptr crtf1 crtf13:push dxcmp score2,58jl normalmov score2,49inc score0 normal:mov dh,0mov dl,8write dh,dl,score2 add dl,score0write dh,dl,zero pop dxcmp adrs,17je jmp1cmp adrs,145je jmp1cmp adrs,31je jmp2cmp adrs,159je jmp2cmp adrs,32je jmp3cmp adrs,160je jmp3cmp adrs,30je jmp4cmp adrs,158je jmp4jmp addrsjmp1:lea ax, turndowncmp ax,addrsje jmp2mov addrs,offset turnupjmp near ptr turnupjmp2:lea ax,turnupcmp ax,addrsje jmp1mov addrs,offset turndownjmp near ptr turndownjmp3:lea ax,turnbackcmp ax,addrsje jmp4mov addrs,offset turnrightjmp near ptr turnrightjmp4:lea ax,turnrightcmp ax,addrsje jmp3mov addrs,offset turnbackjmp near ptr turnbackturnright: ;此处实现蛇向左走push dxmov dh,1mov dl,0mov cx,23cmpr1:push cxmov cx,79cmpr2:readh dh,dlcmp pst,2je nextr4jmp near ptr nextrnextr4:readcg dh,dlpop cxjmp near ptr endrnextr:inc dljmp nextr2chgr2:jmp near ptr cmpr2nextr2:loop chgr2sub dl,79inc dhpop cxjmp nextr1chgr1:jmp near ptr cmpr1nextr1:loop chgr1endr:pop dxinc dlwrite dh,dl,snkjmp near ptr wrt1turnup: ;此处实现蛇向上走push dxmov dh,1mov dl,0mov cx,23cmpu1:push cxmov cx,79cmpu2:readh dh,dlcmp pst,2jne nextu3jmp nextu4nextu3:jmp near ptr nextunextu4:readcg dh,dlpop cxjmp near ptr endunextu:inc dljmp nextu2chgu2:jmp near ptr cmpu2nextu2:loop chgu2sub dl,79inc dhpop cxjmp nextu1chgu1:jmp near ptr cmpu1nextu1:loop chgu1endu:pop dxdec dhwrite dh,dl,snkjmp near ptr wrt1turndown: ;此处实现蛇向下走push dxmov dh,1mov dl,0mov cx,23cmpd1:push cxmov cx,79cmpd2:readh dh,dlcmp pst,2jne nextd3jmp nextd4nextd3:jmp near ptr nextdnextd4:readcg dh,dlpop cxjmp near ptr enddnextd:inc dljmp nextd2chgd2:jmp near ptr cmpd2nextd2:loop chgd2sub dl,79inc dhpop cxjmp nextd1chgd1:jmp near ptr cmpd1nextd1:loop chgd1endd:pop dxinc dhwrite dh,dl,snkjmp near ptr wrt1turnback: ;此处实现蛇向右走push dxmov dh,1mov dl,0mov cx,23cmpb1:push cxmov cx,79cmpb2:readh dh,dlcmp pst,2jne nextb3jmp nextb4nextb3:jmp near ptr nextbnextb4:readcg dh,dlpop cxjmp near ptr endbnextb:jmp nextb2chgb2:jmp near ptr cmpb2nextb2:loop chgb2sub dl,79inc dhpop cxjmp nextb1chgb1:jmp near ptr cmpb1nextb1:loop chgb1endb:pop dxdec dlwrite dh,dl,snkjmp near ptr wrt1exit:mov ax,0 ;恢复int9中断mov es,axpush ds:[0]pop es:[9*4]push ds:[2]pop es:[9*4+2]mov ah,4chint 21hint9: ;更改后的中断服务程序push axin al,60hmov adrs,almov al,20hout 20h,aliretDLY PROC near ;延时子程序PUSH CXPUSH DXMOV DX,10000DL1: MOV CX,9801DL2: LOOP DL2DEC DXJNZ DL1POP DXPOP CXRETDLY ENDPRAND1 PROCPUSH CXPUSH DXPUSH AXSTIMOV AH,0 ;读时钟计数器值INT 1AHMOV AX,DX ;清高6位AND AH,3MOV DL,23 ;除23,产生0~23余数DIV DLMOV frow,AH ;余数存frow,作随机行数POP AXPOP DXPOP CXRETRAND1 ENDPRAND2 PROCPUSH CXPUSH DXPUSH AXSTIMOV AH,0 ;读时钟计数器值INT 1AHMOV AX,DX ;清高6位AND AH,3MOV DL,79 ;除79,产生0~79余数DIV DLMOV fcol,AH ;余数存fcol,作随机列数POP AXPOP DXPOP CXRETRAND2 ENDPCODE ENDSEND start。
贪吃蛇代码预处理#include#include#include#pragma comment(lib,"Winmm.lib")#define width_window 500 //窗口的宽度#define high_window 398 //窗口的高度#define width_gameBoard 398 //游戏区域的宽度#define high_gameBoard 398 //游戏区域的高度#define sw 10 //用一个圆表示蛇的一节,sw表示圆的半径#define num_food 16 //设定的食物个数,全部吃完则游戏胜利结束#define NameMaxLength 12 //设定用户名的最大字符数为:NameMaxLength-2#define PsdMaxLength 10 //设定密码的最大字符数#define boxbkclr 0xfedcbd //绘制消息框和登录框的主题填充颜色#define drawFieldbkclr 0xFFFFFF //窗口区域的背景填充颜色#define MovDist 1 //按钮移动量为MovDist像素void InitGameBoard(); //创建绘图窗口,并初始化void InitSnake(int x0,int y0,int d0); //用随机数产生蛇的位置和方向void SetFood(); //随机地在蛇以外的位置放置食物int GetPlayerCommand(); //获取游戏玩家发出的控制指令void dispScore(); //动态显示得分void dispInfo(); //显示得分、操作指南和版本等信息void bkMusic_launchImg(); //播放背景音乐和添加启动画面void window_segmented(); //画线分割窗口void GameOver(bool iskillde); //判断游戏是否结束void ClearTailNode(); //擦除蛇尾结点void Eat(int x,int y); //吃食物void SnakeMove(int x,int y,int d); //蛇按照玩家的控制命令进行移动void pause(); //游戏暂停void DrawMsgBox(); //绘制消息窗口int ResponseMouse(int,int,int,int,int,int,int,int,int,int,int,int);//响应鼠标void DrawTwoBtn(); //绘制启动画面上的两个按钮void DrawLoginUI(); //绘制登陆界面void InputName(); //输入账号void InputPsd(); //输入密码int ChkNamePsd(char*,char*); //点击登陆,核对用户名和密码//绘制按钮被点击时有被按压下去并回弹的动感void BthMoveClicked(int,int,int,int,int,int,char*);typedef struct snake{int x;int y;struct snake*next;}SNAKE;SNAKE*head=(snake*)malloc(sizeof(snake));int n=0; //初始化放置食物的个数为0int sx=0,sy=0,sd=0; //蛇头的位置坐标和移动方向int xb00=0,xb01=0,xb02=0,xb03=0,xb04=0,xb05=0;//控件(按钮或输入框)的位置坐标int yb00=0,yb01=0,yb02=0,yb03=0,yb04=0,yb05=0;//控件(按钮或输入框)的位置坐标char UserName[5]={'m','a','r','r','y'}; //系统设定的用户名char Password[6]={'t','o','m','1','2','3'}; //系统设定的密码//用于储存用户输入的账号char IptName[NameMaxLength]={'','','','','','','','\0'};//用于储存用户输入的密码char IptPsd[PsdMaxLength]={'','','','','','','','\0'};int isagin=0; //用于判断是否再玩一次,为1表示再玩一次系统主函数void main(){char str_again[]="再来一次"char str_exit[]="我不玩了"while(1){n=0;//每局开始需要初始化放置食物的个数为0InitGameBoard();//创建绘图窗口,并初始化InitSnake(sx,sy,sd);//用随机数的方式在某个位置产生蛇和蛇的移动方向SetFood();//随机地在蛇以外的位置放置食物SnakeMove(sx,sy,sd);//蛇按照玩家的指控命令进行移动DrawMsgBox();//绘制消息窗口isagain=ResponseMouse(xb00,yb00,xb01,yb01,xb02,yb02,x b03,yb03,0,0,0,0);//响应鼠标点击if(isagain==1)//点击了按钮1“再来一次”{BtnMoveClicked(xb00,yb00,xb01,yb01,6,6,str_again);//绘制动态按钮}if(isagain==2)//点击了按钮1“我不玩了”{BtnMoveClicked(xb02,yb02,xb03,yb03,6,6,str_exit);//绘制动态按钮break;}}closegraph();}1、播放背景音乐和添加启动画面void bkMusic_launchImg(){//播放背景音乐mciSendString("open./千年等一回.mp3 alias 千年等一回",0,0,0);mciSendString("play 千年等一回 repeat",0,0,0);//添加启动画面cleardevice();//用当前背景色清空屏幕,并将当前点移至(0,0)IMAGE img;loadimage(&img, _T("SnakesLaunch1.bmp"));//加载图像putimage(0,0,&img);//显示图像作为启动画面}2、划线分割窗口void window_segmented(){setlinecolor(BLUE);setlinestyle(PS_SOLID|PS_ENDCAP_FLAT,6);//设置线条宽度6的实线,平端点setfillcolor(YELLOW);//划线分割窗口line(width_gameBoard+1,0,width_gameBoard+1,high_game Board);line(width_gameBoard+1,200,width_window,200);//划线分割窗口setlinestyle(PS_SOLID|PS_ENDCAP_FLAT,1);//恢复线条样式为宽度1的实线}3、创建绘图窗口,并初始化void InitGameBoard(){int choice;//点击了哪个按钮int ret=-1;//用于表示核对用户名密码是否正确char str_guide[]="操作指南";char str_regist[]="登录游戏"initgraph(width_window,high_window);//创建大小为width_window*high_window的窗口setorigin(0,0);//设置绘图窗口区域的左上角为逻辑坐标原点setbkcolor(0xFFFFFF);//设置背景颜色,0xFFFFFF为白色bkMusic_launchImg();//播放背景音乐和添加启动画面if(isagain!=1)//是否是重新开始一局{DrawTwoBtn();//绘制启动画面上的两个按钮choice=ResponseMouse(xb00,yb00,xb01,yb01,xb02,yb02,xb 03,yb03,0,0,0,0);if(choice==1)//点击了“操作指南”{BtnMoveClicked(xb00,yb00,xb01,yb01,6,6,str_guide);//绘制动感按钮Sleep(200);//加载并显示操作指南图片IMAGE img;loadimage(&img,_T("SnakesLaunch2.bmp"));putimage(0,0,&img);choice=ResponseMouse(-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0);if(choice==0)//点击了鼠标左键{//设置绘图样式setlinecolor(WHITE); //设置线条颜色为白色setlinestyle(PS_SOLID|PS_ENDCAP_FLAT,1); //设置线条样式setfillcolor(YELLOW);}}else//点击了“登录游戏”{BtnMoveClicked(xb02,yb02,xb03,yb03,6,6,str_regist);Sleep(200);}DrawLoginUI();//绘制登陆界面window_segmented();//划线分割窗口while(1){if(ret==0)//判断是否已经发生过输入用户名或密码错误{//设置字体颜色为框体填充颜色,目的是擦掉提示错误的信息setcolor(boxbkclr);//设置输入文本的背景颜色为框体填充颜色,目的是擦掉提示错误的信息setbkcolor(boxbkclr);setbkmode(TRANSPARENT);//设置文字输出时的背景模式为透明色settexstyle(18,0,_T("宋体"));//用框体填充颜色输出错误信息,即擦除outtextxy(xb00-50,yb00-20,"账号或密码输入错误,请重新输入!");setbkcolor(drawFieldbkclr);choice=ResponseMouse(xb00,yb00,xb01,yb01,xb02,yb02,xb 03,yb03,xb04,yb04,xb05,yb05);}choice=ResponseMouse(xb00,yb00,xb01,yb01,xb02,yb02,xb 03,yb03,xb04,yb04,xb05,yb05);if(choice==1){InputName();//输入账号}if(choice==2){InputPsd();//输入密码}if(choice==3){ret=ChkNamePsd(IptName,IptPsd);//点击登录if(ret==1)break;}}}cleardevice();//用当前背景色清空屏幕,并将当前点移至(0,0)window_segmented();//划线分割窗口dispInfo();//显示得分和操作指南信息}4、显示得分、操作指南和版本等信息void dispInfo(){//显示得分情况setcolor(BLACK);//设置字体颜色settextstyle(18,0,_T("黑体"));//设置字体类型outtextxy(width_gameBoard+10,30,"当前得分:"); settextstyle(38,0,_T("黑体"));//设置字体类型outtextxy(width_gameBoard+10,60,"0");//显示操作指南信息settextstyle(18,0,_T("黑体"));//设置字体类型outtextxy(width_gameBoard+10,220,"操作指南"); settextstyle(12,0,_T("宋体"));//设置字体类型outtextxy(width_gameBoard+10,250,"按F或f键向东转");outtextxy(width_gameBoard+10,265,"按S或s键向西转"); outtextxy(width_gameBoard+10,280,"按D或d键向南转"); outtextxy(width_gameBoard+10,295,"按E或e键向北转"); outtextxy(width_gameBoard+10,320,"按A或a键向东转"); outtextxy(width_gameBoard+10,335,"按空格键暂停"); outtextxy(width_gameBoard+10,350,"按ESC键退出");//显示版本信息outtextxy(width_gameBoard+10,380,"**贪吃蛇V1.0.0"); }5、动态显示得分void dispScore(){char str_score[6];int num_score=0;num_score=(n-1)*10;//每吃一个得10分itoa(num_score,str_score,10);//数字转化为字符setcolor(RED);setbkmode(OPAQUE);settextstyle(38,0,_T("黑体"));outtextxy(width_gameBoard+10,60,str_score);//显示得分}6、用随机数的方式在某个位置产生蛇和蛇的移动方向void InitSnake(int x0,int y0,int d0){int x,y,d;//蛇的初始位置(x,y)和蛇的移动方向d//用伪随机数产生蛇的初始位置(x,y)和物体的移动方向d//注意:(x,y)不要太靠近四个边,否则可能会出现游戏刚开始就结束了的情况。
“贪吃蛇”游戏程序代码我个人是比较喜欢玩游戏的,所以学习编程二年多了,很想做个游戏程序,由于能力有限,一直没能做好,后来突然看同学在手机上玩“贪吃蛇”,故想做出来,其一是因为此游戏界而容易设计,算法也比较简单,今天我就把我程序的代码和算法介绍一下,顺便把程序界而皮肤设计说一下.....程序中一个关于游戏信息的类如下,由于类的说明在程序中写的很清楚了,就不再多解释了:#include"time,h"〃方向定义const CPoint UP(CPoint(0,-1));const CPoint DOVN(CPoint(0,1));const CPoint LEFT(CPoint(-1,0)):const CPoint RIGHT(CPoint(1,0)):〃速度快慢定义const int HIGH =75;const int NORMAL =180;const int SLOW =300;const int MAX =80;〃表示转向数const int LENGTH=10;class GamcMsgpublic:GamcMsg(void):m_icon(0)InitGame();void InitGame(int up=VK_UP,int down = VK_DOWN,int left= VK.LEFT,int right= VK.RIGHT?(srand((unsigned)time(NULL));m_gameSpeed= NORMAL;m_speedNum=2;m_snakeNum=4:for(int i=0;i<m_snakcNum;++i)m_snakePoint[i]=CPoint(5+LENGTH*2*5+LENGTH,LENGTH*2*(i+5));m_run=true:m_direction=RIGHT;turnUP=up;turnDOWN=down;turnLEFT =left:turnRIGHT=right;}public:int m_gamcSpeed;//游戏速度int m_speedNum;//游戏速度数CPoint m_foodPoint:〃食物定义bool m_run;〃游戏状态,运得态还是暂停(结束)态CPoint m_snakePoint[MAX]:〃蛇身定义CPoint m_direction://蛇运动方向int m_snakeNum;〃蛇身结点数int m.icon;//用来设定食物是那种图标的int turnUP://用来表示玩家“上”键设的键int turnDOWN;〃用来表示玩家“下”键设的键int turnLEFT;//用来表示玩家“左”键设的键int turnRIGHT;//用来表示玩家“右”键设的键int m_num;//用来记录所选水果的编号);再让读者看一下程序主干类的设计,其中以下只列出由我们自己添加的一些变量的说明,其他的是由程序向导自动生成的,我就不说了:public:afx_msg void OnTimer(UINT_PTR nIDEvent);//程序中运行函数,即是一个定时器,时间就是上而类中的m_gameSpecd来控制的CStatic*m_staticArray;//这是一个蛇定义,是用来显示蛇的,上面只告诉蛇身结点的中心点位置坐标,然后在此中心画一个控件就类似于蛇身了afx.msg void OnCloseO://结束,主要是在其中销毁定时器的void GamcOver(void);//游戏结束函数afx_msg void OnRButtonDown(UINT nFlags,CPoint point);//当点击鼠标右键出现菜单afx_msg void OnNewGameO;//菜单选项,新游戏afx_msg void OnPauseOrStart();〃菜单选项,暂停/开始游戏afxjnsg void OnUpdatcQuick(CCmdUI*pCmdUI);//这3个函数本来是来标记速度的,和上面类中的m_speedNum对应,但是没有标记成功afx.msg void OnUpdateNormal(CCmdUI*pCmdUI);afx_msg void OnUpdateSlow(CCmdUI*pCmdUI):afx_msg void OnNormal0;//菜单选项,设定为普通速度afx_msg void OnSlowO;〃菜单选项,设定为慢速度afx_msg void OnQuickO;//菜单选项,设定为快速度afx_msg void OnlntroduceO://游戏介绍,就是弹出一个对话框而以afx_msg void OnMoreprogram();〃进入我的博客的函数afx_msg void OnAbout():〃关于"贪吃蛇”说明的对话框afx_msg void OnExit();//退出游戏CFont m.font;〃这就是上图中显示"空心字体”的亍体设置void ShowHo11o wFont(int ex,int cy,CString str)://显示空心字体函数,在(Cx,Cy)处显示字符串strafx_msg void OnBnClickedExit();//退出游戏private:int m_iconl;//表明蛇吃第1种水果的个数int m_icon2://表明蛇吃第2种水果的个数int m_icon3://表明蛇吃第3种水果的个数然后给读者写的是我程序运行很重要的一个函数,W3!_TIMER显示函数,里面有食物位置随机出现,判断蛇死,蛇移动等:void CSnakeDlg::OnTimer(UINT_PTR nIDEvent)(if(game.m_snakePoint[0].x<011game.m_snakePoint[0].y<LENGTH I|game.m_snakePoint[0].x>70011game.m_snakePoint[0].y>500)//当蛇跑出边算,游戏结束(GamcOver();}for(int j=game.m_snakeNum-l:j>0;—j)//蛇移动的量的变化,当重新设定这些控件的位置时也就是让蛇移动起来game.m_snakePoint[j]=game.m_snakePoint[j-1];game.m_snakePoint[0].x+= game.m_di recti on.x* LENGTH * 2;//蛇头移动game.m_snakePoint[0].y+= game.m_di recti on.y*LENGTH * 2;for(int i=0;i<game.m_snakcNum;++i){m_staticArray[i].SetWindowPos(NULL,game.m_snakePoint[i],x-LENGTH,game.m_snakePoint[i].y-LENGTH,game.m_snakePoint[i].x+ LENGTH,game.m_snakePoint[i].y+LENGTH,SW_SHOW);}for(int j=l;j<game.m_snakcNum;++j)//当蛇撞到自己也结束游戏if(game.m_snakcPoint[0]=game.m_snakePoint[j]){GamcOver();)m.staticArray[NIAX].ModifyStyle(OxF,SS_ICON|SS_CENTERIMAGE);〃显示水果m_stat icArray[MAX].Set Icon(AfxGetAppO->LoadIcon(game.m_icon));m_stat icArray[MAX].SetWi ndowPos(NULL,game.m_foodPoint.x,game.m_foodPoint.y,32,32,SW_SHOW);〃当蛇吃到水果if(game.m_snakePoint[0].x<game.m_foodPoint.x+20+LENGTH&& game.m_snakePoint[0].x>game.m_foodPoint.x-LENGTH&&game.m_snakePoint[0].y<game.m_foodPoint.y+20+LENGTH&&game.m_snakePoint[0].y>game.m_foodPoint.y-LENGTH)(game.m_foodPoint= CPoint(LENGTH*gamc.RandNum(2,37),LENGTH*game.RandNum(2,27));CString str:if(game.m_num =0){++m_iconl;str.Formatm_iconl);GetDlgItem(IDC_EDITl)->SetWindowTextA(str);else if(game.m_num =1)++m_icon2;str.Formatm_icon2);GetDlgItem(IDC_EDIT2)->SetWindowTextA(str):)else{++m_icon3:str.Format(飞d”,m_icon3);GetDlgItem(IDC_EDIT3)->SetWindowTextA(str);}game.m_num = game.RandNum(0,3);game.m_icon=IDI_ICON1+game.m_num;//重新加1个水果game.m_snakeNum++;〃蛇的长度加1str.Format(*%<!*,game.m_snakeNum);GetDlgItem(IDC_EDIT4)->Se t W i ndowTextA(str):)CDialog::OnTimer(nIDEvent);)如下再介绍应用在对话框中来响应键盘消息,我写的是一个键盘“钩子”,代码如下:HHOOK g_hKcyboard=NULL;HWND g_hWnd= NULL:LRESULT CALLBACK KeyboardProc(int code,//hook code WPARAM wParam,//virtual-key code LPARAM1Param //keystroke-message information)(if(wParam=game.turnUP){if(game.m_direction.y=0)game.m_direction=UP;}else if(wParam=game.turnDOWN)(if(game.m_direction.y=0)game.m_direction=DOWN:)else if(wParam=game.turnLEFT){if(game.m_direction.x=0)game.m_direction=LEFT:)else if(wParam=game.turnRIGHT){if(game.m_direction.x=0)game.m_direction=RIGHT;)elsereturn1;然后介绍一下,点击鼠标右键出现菜单:voidCSnakcDlg::OnRButtonDown(UINT nFlags,CPoint point){if(game.m_run)KillTimer(l);CMenu oMenu;if(oMenu.LoadMenu(IDR.MENU1))(CMenu*pPopup = oMenu.GetSubMcnu(O);ASSERT(pPopup!=NULL);CPoint oPoint:GetCursorPos(&oPoint);SetForegroundWindowO;pPopup->TrackPopupMenu(TPM_LEFTALIGN,oPoint.x,oPoint.y,this);}if(game.m_run)SetTimer(1,game.m_gameSpeed,NULL);CDialog::OnRBu11onDown(nF1ags,point);}然后来介绍一下程序中是怎样来改变按键的,首先说一下,我开始用EDIT控件来让用户输入,但是程序中我用的是键盘"钩子”来处理消息的,所以EDIT 控件在程序中是不可以输入信息的,所以我选的是下拉列表,代码如下,解释也在程序中相应给出:int keyNum[40]={〃定义玩家可以设的键,把所有的健信息存在这个数组中VK.UP,VK.DOWN,VK.LEFT,VK.RIGHT,VK.NUMPADO,VK_NUMPAD1,VK.NUMPAD2,VK.NUMPAD3,VK_NUMPAD4,VK_NUMPAD5, VK NUMPAD6,VK NUMPAD7,VK NUMPAD8,VK NUMPAD9);void CSnakeDlg::0nKeyset()//键盘设置响应消息函数//T0D0:在此添加命令处理程序代码if(game.m_run)KillTimer(l);CKcySetDlg dig:if(dig.DoModalO=IDOK)(if(dig.m_up =dig.m_down11dig.m_up =dig.m_left||dig.m_up =dig.m_right||dig.m_down=dig.m_left||dig.m_down ==dig.m_right||dig.m_left=dig.m_right)(MessageBox(w键位不能设置为重复的,设置失败!");if(game.m_run)SetTimcr(1,game.m_gamcSpeed,NULL);return;}game.turnUP =kcyNum[GetMarkNum(dlg.m_up)]://重新设置键game.turnDOWN=keyNum[GetMarkNum(dlg.m_down)]:game.turnLEFT =keyNum[GetMarkNum(dlg.m_left)];game.turnRIGHT =keyNum[GetMarkNum(dlg.m_right)];}if(game.m_run)SetTimcr(1,game.m_gamcSpeed,NULL);}int CSnakcDlg::GetMarkNum(CString str)//返回重新设置键对应数组的“索引”int backNum = 0;if(str="上")backNum = 0:else if(str=="下”) backNum =1:else if(str=="左") backNum=2;else if(str="右") backNum=3:else{CString ss;for(char i='A';i〈='Z';++i) {ss.Format(飞c”,i);if(ss―str.Right(l))(backNum=i-'A'+4;return backNum;})for(int i=0:i<=9:++i)ss.Format("%d",i);if(ss=str.Right(1))(backNum=i+30;return backNum;})}return backNum;)最后写一下程序更换皮肤的一段代码,本来觉得不算很难的,不过还是介绍一下吧,对了我用的是Skinmagic做的皮肤,不过这个软件你可以通过网上的说明进行注册,也可以自己把它破解,其实很简单,大家可以试试:void CSnakeDlg::0nChangSkin()(//T0D0:在此添加命令处理程序代码i f(game.m_run)KillTimer(l);CFileDialog dig(TRUE,NULL,NULL,OFN.HIDEREADONLY|OFN.OVERWRITEPROMPT,"Skin Files(*.smf7|*.smf|T,AfxGetMainWndO);CString strPath,strText="";if(dig.DoModalO=IDOK)(strPath=dig.GetPathNamcO:VERIFYd=LoadSkinFile(strPath));if(game.m_run)SetTimerd,game.m_gameSpeed,NULL);)还有很多小函数,由于都是比较简单的,就不多写了,程序介绍就到这里,呵呵,希望我能够帮你解决你写程序遇到的问题,如果大家想知道如何做程序的皮肤的话,网上有很多这样的博客,我就是在那样的博客里学到的,如果还是想我来介绍的话,那给我留言说下哦,呵呵,谢了,有问题请在下面留言.。
贪吃蛇编程的知识点总结1. 游戏界面的绘制在贪吃蛇游戏中,需要将游戏界面绘制出来,可以使用常见的游戏开发库,比如pygame 进行绘制。
需要考虑的知识点有窗口创建、绘制蛇、食物、边界和其他的游戏元素。
2. 蛇的移动和控制蛇的移动需要根据玩家的控制进行更新,比如按下上下左右键盘控制蛇的方向。
在实现过程中需要考虑蛇头的移动、蛇身体的增长和移动以及蛇头和蛇身体的碰撞检测等知识点。
3. 食物的生成和吃掉游戏中需要随机生成食物,并且当蛇头吃到食物时需要让食物消失并且蛇的身体增长。
食物的生成和消失需要考虑到随机数的生成以及碰撞检测等知识点。
4. 游戏逻辑的实现在游戏逻辑的实现中,需要考虑到蛇头撞到边界、蛇头撞到自己的身体、得分的计算以及游戏重新开始等逻辑处理的知识点。
5. UI界面的美化为了增加游戏的娱乐性和可玩性,可以对游戏界面进行美化,比如增加背景音乐、游戏结束的动画效果等知识点。
6. 优化和性能调优在开发过程中需要考虑到性能的问题,比如蛇的移动速度、食物的生成速度、碰撞检测的效率等知识点。
7. 存档和排行榜为了提升游戏的可玩性,可以考虑添加存档和排行榜功能,需要考虑到文件操作、数据存储和读取、数据排序等知识点。
8. 多平台支持为了让更多的玩家可以进行游戏,可以考虑将游戏适配到多个平台,比如PC端、移动端等知识点。
9. 多人游戏功能在一些派生的贪吃蛇游戏中,增加了多人游戏的功能。
这时需要考虑到网络通信、玩家控制、多个蛇的移动、碰撞检测和游戏逻辑的处理等知识点。
总的来说,开发贪吃蛇游戏所涉及到的知识点包括游戏界面的绘制、蛇的移动和控制、食物的生成和吃掉、游戏逻辑的实现、UI界面的美化、优化和性能调优、存档和排行榜、多平台支持、多人游戏功能等多个方面。
通过开发贪吃蛇游戏,可以锻炼程序员的编程能力和逻辑思维能力,是一个很好的编程练习项目。
android游戏开发入门: 贪吃蛇 源代码分析贪吃蛇是一款足够经典的游戏。
它的经典,在于用户操作的简单,在于技术实现的简介,在于他的经久不衰。
这里的贪吃蛇的android实现,是SDK Samples中的开源例程。
可能各位都有看过~界面如下图啦~作为一个刚入门或者还没入门的新手,着实花了我一些力气来理解这段代码。
对于各种不懂的地方,慢慢查询资料,对于新的方法,通过修改代码尝试效果。
到现在终于能算个一知半解。
在代码中,对于自己有所收获的地方,我都做了相应的注释。
回过头来,觉得从这段代码中,能学到不少东西~~包括android应用的基本架构,他的面向对象的思想,以及代码的简洁明了。
于是,我想到,何不将这些东西分享出来,如果碰巧对感兴趣的朋友们有搜帮助,那就更好了~好了,闲话不说~代码和注释如下(处于对源码的敬意,原本的英文注释部分都没有删去~大家可以配合理解):PS:最近我正在写自己的“贪吃蛇”,说事贪吃蛇,其实完全颠覆了这个经典版本的设计理念和操作方式。
具体细节先卖一个关子,作品准备参加这次第二届大学生android应用开发大赛。
应该一个月内能完成,到时候也会开源出代码来~欢迎大家讨论指正·~*************************************************************************************************************************** *****Snake工程中,总共有三个文件: *TileView是基于Android的View类实现的方块图类,用来支撑上层类的调用,绘制方块图的显示界面。
通过这些代码,能打之了解如何 扩展View,实现特色的界面效果。
*SnakeView调用了TileView,实现了游戏逻辑 和 具体的显示。
*Snake为主Activity类。
建议大家按照上面的顺序看三个文件,可能逻辑上更舒服一点~~下面贴上代码和注释。
游戏贪吃蛇的JAVA源代码一.文档说明a)本代码主要功能为实现贪吃蛇游戏,GUI界面做到尽量简洁和原游戏相仿。
目前版本包含计分,统计最高分,长度自动缩短计时功能。
b)本代码受计算机系大神指点,经许可后发布如下,向Java_online网致敬c)运行时请把.java文件放入default package 即可运行。
二.运行截图a)文件位置b)进入游戏c)游戏进行中三.JAVA代码import java.awt.*;import java.awt.event.*;import static ng.String.format;import java.util.*;import java.util.List;import javax.swing.*;public class Snake extends JPanel implements Runnable { enum Dir {up(0, -1), right(1, 0), down(0, 1), left(-1, 0);Dir(int x, int y) {this.x = x; this.y = y;}final int x, y;}static final Random rand = new Random();static final int WALL = -1;static final int MAX_ENERGY = 1500;volatile boolean gameOver = true;Thread gameThread;int score, hiScore;int nRows = 44;int nCols = 64;Dir dir;int energy;int[][] grid;List<Point> snake, treats;Font smallFont;public Snake() {setPreferredSize(new Dimension(640, 440));setBackground(Color.white);setFont(new Font("SansSerif", Font.BOLD, 48));setFocusable(true);smallFont = getFont().deriveFont(Font.BOLD, 18);initGrid();addMouseListener(new MouseAdapter() {@Overridepublic void mousePressed(MouseEvent e) {if (gameOver) {startNewGame();repaint();}}});addKeyListener(new KeyAdapter() {@Overridepublic void keyPressed(KeyEvent e) {switch (e.getKeyCode()) {case KeyEvent.VK_UP:if (dir != Dir.down)dir = Dir.up;break;case KeyEvent.VK_LEFT:if (dir != Dir.right)dir = Dir.left;break;case KeyEvent.VK_RIGHT:if (dir != Dir.left)dir = Dir.right;break;case KeyEvent.VK_DOWN:if (dir != Dir.up)dir = Dir.down;break;}repaint();}});}void startNewGame() {gameOver = false;stop();initGrid();treats = new LinkedList<>();dir = Dir.left;energy = MAX_ENERGY;if (score > hiScore)hiScore = score;score = 0;snake = new ArrayList<>();for (int x = 0; x < 7; x++)snake.add(new Point(nCols / 2 + x, nRows / 2));doaddTreat();while(treats.isEmpty());(gameThread = new Thread(this)).start();}void stop() {if (gameThread != null) {Thread tmp = gameThread;gameThread = null;tmp.interrupt();}}void initGrid() {grid = new int[nRows][nCols];for (int r = 0; r < nRows; r++) {for (int c = 0; c < nCols; c++) {if (c == 0 || c == nCols - 1 || r == 0 || r == nRows - 1)grid[r][c] = WALL;}}}@Overridepublic void run() {while (Thread.currentThread() == gameThread) {try {Thread.sleep(Math.max(75 - score, 25));} catch (InterruptedException e) {return;}if (energyUsed() || hitsWall() || hitsSnake()) {gameOver();} else {if (eatsTreat()) {score++;energy = MAX_ENERGY;growSnake();}moveSnake();addTreat();}repaint();}}boolean energyUsed() {energy -= 10;return energy <= 0;}boolean hitsWall() {Point head = snake.get(0);int nextCol = head.x + dir.x;int nextRow = head.y + dir.y;return grid[nextRow][nextCol] == WALL;}boolean hitsSnake() {Point head = snake.get(0);int nextCol = head.x + dir.x;int nextRow = head.y + dir.y;for (Point p : snake)if (p.x == nextCol && p.y == nextRow)return true;return false;}boolean eatsTreat() {Point head = snake.get(0);int nextCol = head.x + dir.x;int nextRow = head.y + dir.y;for (Point p : treats)if (p.x == nextCol && p.y == nextRow) {return treats.remove(p);}return false;}void gameOver() {gameOver = true;stop();}void moveSnake() {for (int i = snake.size() - 1; i > 0; i--) {Point p1 = snake.get(i - 1);Point p2 = snake.get(i);p2.x = p1.x;p2.y = p1.y;}Point head = snake.get(0);head.x += dir.x;head.y += dir.y;}void growSnake() {Point tail = snake.get(snake.size() - 1);int x = tail.x + dir.x;int y = tail.y + dir.y;snake.add(new Point(x, y));}void addTreat() {if (treats.size() < 3) {if (rand.nextInt(10) == 0) { // 1 in 10if (rand.nextInt(4) != 0) { // 3 in 4int x, y;while (true) {x = rand.nextInt(nCols);y = rand.nextInt(nRows);if (grid[y][x] != 0)continue;Point p = new Point(x, y);if (snake.contains(p) || treats.contains(p))continue;treats.add(p);break;}} else if (treats.size() > 1)treats.remove(0);}}}void drawGrid(Graphics2D g) {g.setColor(Color.lightGray);for (int r = 0; r < nRows; r++) {for (int c = 0; c < nCols; c++) {if (grid[r][c] == WALL)g.fillRect(c * 10, r * 10, 10, 10);}}}void drawSnake(Graphics2D g) {g.setColor(Color.blue);for (Point p : snake)g.fillRect(p.x * 10, p.y * 10, 10, 10);g.setColor(energy < 500 ? Color.red : Color.orange);Point head = snake.get(0);g.fillRect(head.x * 10, head.y * 10, 10, 10);}void drawTreats(Graphics2D g) {g.setColor(Color.green);for (Point p : treats)g.fillRect(p.x * 10, p.y * 10, 10, 10);}void drawStartScreen(Graphics2D g) {g.setColor(Color.blue);g.setFont(getFont());g.drawString("Snake", 240, 190);g.setColor(Color.orange);g.setFont(smallFont);g.drawString("(click to start)", 250, 240);}void drawScore(Graphics2D g) {int h = getHeight();g.setFont(smallFont);g.setColor(getForeground());String s = format("hiscore %d score %d", hiScore, score);g.drawString(s, 30, h - 30);g.drawString(format("energy %d", energy), getWidth() - 150, h - 30); }@Overridepublic void paintComponent(Graphics gg) {super.paintComponent(gg);Graphics2D g = (Graphics2D) gg;g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);drawGrid(g);if (gameOver) {drawStartScreen(g);} else {drawSnake(g);drawTreats(g);drawScore(g);}}public static void main(String[] args) {SwingUtilities.invokeLater(() -> {JFrame f = new JFrame();f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);f.setTitle("Snake");f.setResizable(false);f.add(new Snake(), BorderLayout.CENTER);f.pack();f.setLocationRelativeTo(null);f.setVisible(true);});}}。
河北农业大学本科毕业论文题目:贪吃蛇小游戏1.导论 (1)1.1 Android简介 (1)1.1.1 Android的发展 (1)1.1.2 Android系统的特点 (2)1.1.3 Android的系统架构 (2)1.2 项目简介 (3)1.3 项目背景与意义 (3)1.3.1 开发背景 (3)1.3.2 开发意义 (3)1.4 国内外现状分析 (4)1.4.1 国内外手机系统现状 (4)1.4.2 国内外手机应用现状 (5)1.4.3 发展趋势 (5)2. 系统的开发方法及相关技术 (7)2.1 软件工程的定义 (7)2.2 软件工程的模型 (7)2.3 本项目的研究方法 (7)2.3.1 本项目采用的开发模型 (8)2.3.2 本项目的开发方法 (8)2.4 开发工具及环境简介 (9)2.4.1 开发工具eclipse简介 (9)2.4.2 开发环境简介 (10)3. 需求分析 (11)3.1系统开发目标 (11)3.2 系统需求分析 (11)3.2.1 业务需求分析 (11)3.2.2 用户需求分析 (11)3.2.3 功能需求分析 (12)4 概要设计 (13)4.1 程序流程设计 (13)4.2模块设计 (13)4.2.1 模块划分 (13)4.2.2 游戏主界面模块 (14)4.2.3 游戏控制模块 (14)4.2.4 游戏数据模块 (15)4.3 模块实现原理 (15)4.3.1游戏界面模块实现 (15)4.3.2 游戏控制模块实现 (16)4.3.3 数据存储模块实现 (17)5.详细设计 (18)5.1 游戏类图 (18)5.2 游戏界面具体实现 (18)5.2.1 蛇身、食物和墙的实现 (18)5.2.2 处理键盘事件 (19)5.2.3 TileView类的设计 (19)5.2.4 SnakeView类的设计 (19)5.2.5 Snake类的详细设计 (19)5.2.6 程序主结构 (20)5.3 游戏运行界面截图 (20)结论 (22)参考文献 (23)致谢 (24)1.导论随着移动通信的发展以及互联网向移动终端的普及,网络和用户对移动终端的要求越来越高,而Symbian,Windows Mobile,PalmOS等手机平台过于封闭,不能很好的满足用户的需求,因此市场迫切需要一个开放性很强的平台。
目录1程序简介 (1)2程序设计 (1)2.1程序分析程序初始化: (1)2.2游戏流程 (2)2.3程序流程图 (3)2.4数据定义及重要函数 (4)3系统测试及改进 (12)3.1程序测试 (12)3.2系统改进 (14)4源码 (15)1程序简介贪吃蛇游戏是一个经典小游戏,在封闭的围墙里面,通过键盘的上下左右控制蛇的方向,寻找随机出现的食物。
蛇头撞到食物,则食物被吃掉,蛇身体长度+1,同时记100分,蛇的身子越吃越长,身子越长玩的难度就越大,如果蛇在移动中撞到墙或身体交叉蛇头撞倒自己身体游戏结束。
2程序设计2.1程序分析程序初始化:加载在数据段定义好相关的提示信息以及储存蛇身的数组,主要是如何开始游戏的提示信息蛇的移动:程序的关键是表示蛇的图形以及蛇的移动。
一开始用4个小矩形表示蛇的身体,每吃一个食物,身体增加一个矩形,移动时必须从蛇头开始,所以蛇不能向相反方向移动,蛇头的前进方向也就是蛇的方向,蛇尾不能改作蛇头。
设置一个等待时间,如果不按任何按键,蛇在当前方向上前进。
按了有效的方向键后,先确定蛇头的位置然后蛇身体随着蛇头移动,图形的实现是从蛇头的新位置开始画出蛇,这时由于没有清屏的原因,原来蛇的位置和新蛇的位置相差一个单位,所以看起来蛇会多一节身体。
食物的产生:通过一系列运算产生在要求范围内的的随机数,此时的随机数便是随即点,可以通过产生的随即点的坐标画出随即点,也就是食物了。
蛇吃食物:蛇头的位置可以与随即点的位置坐标判断,如果此时两点的坐标是相同的,那么该食物被蛇吃掉,蛇的长度+1。
判断游戏结束的条件:当蛇的头部位置坐标与边界坐标重合或者蛇头的位置与自身相重合,游戏结束暂停:游戏过程中,按空格键可以使游戏暂停,在按空格键进入被暂停的游戏2.2游戏流程由程序分析知,该游戏是用方向键实现贪吃蛇的移动,游戏大概流程分为:游戏初始化(描绘围墙、蛇体、食物等及其颜色),游戏过程(通过四个方向键控制蛇头带动身体移动),游戏结束(显示总分并判断是否重新游戏)。
贪吃蛇的java代码分析(⼆)1. 代码剖析贪吃蛇是⼀款⼗分经典的⼩游戏,对初⼊coding的朋友来说,拿贪吃蛇这样⼀个案例来练⼿⼗分合适,并不⾼的难度和成功后的成就感都是学习所必须的。
下⾯我将依照我当时的思路,来逐步分析实现的整个过程。
让我们逐⼀分析。
⾸先,整个游戏最基本的元素是地图。
在java中⽤于绘图的类是swing和awt,在这⾥主要⽤到swing类。
swing中⽤于窗⼝显⽰的类有JFrame及其⼦类。
JFrame可以直接添加组件,但其本质是将组件添加到JFrame中的⼀个默认⾯板⾥,为了代码清晰,我会使⽤JPanel⾯板来绘制全部的动画,之后再将⾯板添加到JFrame窗体之中即可。
我们可能会疑惑于贪吃蛇的蛇⾝,它是由什么组成的?如何实现移动?我们可以把贪吃蛇的蛇⾝理解成⼀个集合,它有固定的起始元素,代表游戏⼀开始时的蛇⾝。
当贪吃蛇吃到点时,集合就添加⼀个元素,蛇的长度就加⼀。
那么,集合中的元素是什么呢?要理解这个问题,⾸先得关注蛇⾝移动所处的环境。
在JFrame窗体中,是由X、Y轴坐标对位置进⾏区分。
贪吃蛇的蛇⾝可以看做是⼀个⼀个联系紧密的点,在坐标轴上显⽰出来。
每当朝某个⽅向移动时,蛇的坐标就按照某个规律变化。
例如,我们操控贪吃蛇向上移动时,蛇的全体坐标的Y轴就减⼀;如果蛇的第⼀个坐标与蛇⾝的某个坐标重合,就代表贪吃蛇碰到⾃⼰;如果蛇的第⼀个坐标碰到了边界,蛇就撞墙。
这就是贪吃蛇的本质。
我们来建⽴建⽴蛇⾝上每⼀个点的对象,蛇⾝就是由⼀个⼀个这样的对象所组成的:public class snakeNode {private int x;private int y;private String color;public snakeNode() {};public snakeNode(int x, int y, String color) {this.x = x;this.y = y;this.color = color;}public int getX() {return x;}public void setX(int x) {this.x = x;}public int getY() {return y;}public void setY(int Y) {this.y = y;}public String getColor() {return color;}public void setColor(String color) {this.color = color;}这串代码表⽰蛇⾝上的每⼀个点,通过建⽴snakeNode的对象,指定不同的X轴和Y轴的值,就能组成⼀个蛇⾝。
XXXX学院计算机科学系《Android程序设计》课程设计报告题目:贪吃蛇专业:计算机科学与技术班级: B11计科班2014年6月目录第一章绪论 (2)1.1游戏简介 (2)1.2开发目的及意义 (3)1.3开发环境及工具 (3)第二章需求分析 (4)2.1游戏界面分析 (4)2.2游戏角色分析 (4)2.3游戏控制分析 (4)第三章总体设计 (5)3.1系统功能模块层次图 (5)3.2运行机制 (6)3.3贪吃蛇功能流程图 (7)第四章详细设计与实现 (9)4.1 SnakeActivity类 (9)4.2 MyTile类 (10)4.3 NextActivity类 (18)4.4 SysApplication类 (19)4.5界面设计 (20)第五章测试 (24)5.1功能测试 (24)5.4测试结果 (25)第六章结论 (25)第一章绪论1.1游戏简介贪吃蛇游戏是一款手机游戏,同时也是一款比较需要耐心的游戏。
贪吃蛇游戏是一条蛇,不停地在手机屏幕上游走,吃在手机屏幕上出现的食物。
当蛇吃掉1个食物后会变长,并且吃完食物时食物会消失,并立即随机生成1个新的食物,只要蛇头碰到屏幕四周或者碰到自己的身子,蛇就立即毙命。
1.2开发目的及意义通过本次课程设计,了解android软件的开发过程,熟悉并掌握JA V A语言,程序关键在于表示蛇的图形及蛇的移动。
用一个小矩形块表示蛇的一节身体,身体每长一节,增加一个矩形块,蛇头用一节表示。
移动时必须从蛇头开始,所以蛇不能向相反的方向移动,如果不按任意键,蛇自行在当前方向上前移,但按下有效方向键后,蛇头朝着该方向移动,一步移动一节身体,所以按下有效方向键后,先确定蛇头的位置,而后蛇的身体随蛇头移动。
意义是方便人们在休闲时通过玩手机游戏获得一点快乐,同时锻炼自己的大脑。
1.3开发环境及工具在Window8下进行,采用eclipse开发工具,基于安卓2.2操作系统。
Android ----snake源码分析代码结构分析:Snake :主游戏窗口SnakeView:游戏视图类,是实现游戏的主体类TileView :一个处理图片或其它Coordinate :这是一个包括两个参数,用于记录X轴和Y轴简单类,其中包括一个比较函数.RefshHandler :用于更新视图Snake这个类是游戏的主游戏窗口,是框架容器。
1.游戏的开始:oncreate此外的亮点是:setContentView(yout.snake_layout);设置窗口的布局文件,这里Android123给大家说明的是,这里的snake_layout使用了自定义资源标签的方式,大家注意学习:这里我们可以看到来自SnakeView这个派生类的名称,由于Android内部的R.资源不包含SnakeView类,所以我们必须写清楚Package,比如com.exmple.android.snake.SnakeView 然后和其他控件使用一样,都是一个id然后宽度、高度、以及自定义的标签tileSize(尾巴长度),如下:<com.example.android.snake.SnakeViewandroid:id="@+id/snake"android:layout_width="fill_parent"android:layout_height="fill_parent"tileSize="12"/>2.onPause:关于这点,大家可以参考下在我blog中关于active生命周期/admin/blogs/379826在玩游戏过程中,如果有来电或是其它事件中断,这时应该把当前状态保存。
以便返回时,还可以继续玩游戏。
这就使用onSaveInstanceState实现保存当前状态。
TileView注:此部分解析来自: Android示例程序Snake贪食蛇代码分析(三)TileView,从名称上不难看出这是一个方砖类,就是生成一个方块。
TileView使用了Android平台的显示基类View,View类是直接从ng.Object派生出来的,是各种控件比如 TextView、EditView的基类,当然包括我们的窗口Activity类,这些在SDK文档中都说的比较清楚。
这里定义了 5个int型全局的变量,分别是方砖的数量mTileSize;方砖水平x防线的数量mXTileCount;以及竖直y方向上的方砖数量 mYTileCount,下面是一个相对偏移位置mXOffset和mYOffset;这里android123主让要大家了解如何自定义View在 Android开发中,在一个View类中主要是重写onSizeChanged方法来控制改变部分,以及onDraw 实现画布的修改,实现的简写如下:@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {} @Overridepublic void onDraw(Canvas canvas) { super.onDraw(canvas);} 我们自定义的TileView类需要自己添加一个构造方法,根据需要,我们还重载了一种包含样式的方法,这里大家可以多看下Gallery控件的实现,就好理解了,下面是基本框架。
public TileView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);}public TileView(Context context, AttributeSet attrs) { super(context, attrs);}在贪食蛇游戏中我们知道Snake是移动的,所以加入了一个清除显示的clearTiles方法,通过一个二维数组保存一个gird网格型的运动轨迹,下一次我们将会讲解android贪食蛇的游戏逻辑和完整的关联拼接实现。
SnakeView在这个类中实现的游戏的实体,从游戏需求的角色,这个游戏包括了如下方面:1.随机产生小苹果,apples这里是复数,当然是是大于1个苹果,所以代码中产生了两个苹果。
2.游戏状态管理3.画蛇,view的更新4.吃掉苹果后小蛇状态的变化5.画围墙如果实现吃掉苹果小蛇速度变快?关键是:mMoveDelay这个变量,以下是涉及到这个变量的函数,每次吃掉苹果后,就会updateSnake一下,里面就把时间处理了:mMoveDelay *= 0.9;小蛇其实就是一个数组,google的代码就是好注释写的清楚:/***mSnakeTrail:a list of Coordinates that make up the snake's body *mAppleList:the secret location of the juicy apples the snake craves.*/private ArrayList<Coordinate> mSnakeTrail= new ArrayList<Coordinate>(); private ArrayList<Coordinate> mAppleList= new ArrayList<Coordinate>();mSnakeTrail:一个由Coordinates列表组织的蛇身.mAppleList:存放鲜美多汁的苹果列表通过这个数组画出小蛇不难,问题是如何判断游戏是否结束?问题是如何判断游戏的状态所有以下的代码来自updateSnake1.吃了苹果// Look for applesint applecount = mAppleList.size();for (int appleindex = 0; appleindex < applecount; appleindex++) {Coordinate c = mAppleList.get(appleindex);if (c.equals(newHead)) {mAppleList.remove(c);addRandomApple();mScore++;mMoveDelay *= 0.9;growSnake = true;}}2.碰到了自己// Look for collisions with itselfint snakelength = mSnakeTrail.size();for(int snakeindex = 0; snakeindex < snakelength; snakeindex++) {Coordinate c = mSnakeTrail.get(snakeindex);if (c.equals(newHead)) {setMode(LOSE);return;}}3.碰到墙了// Collision detection// For now we have a 1-square wall around the entire arenaif ((newHead.x < 1) || (newHead.y < 1) || (newHead.x > mXTileCount - 2) || (newHead.y > mYTileCount - 2)) {setMode(LOSE);return;}源代码分析Snake状态分析:在snakeView中定义了snake游戏的几种状态:private int mMode = READY;public static final int PAUSE = 0; //暂定public static final int READY = 1; //准备好了public static final int RUNNING = 2;//正在运行public static final int LOSE = 3; //结束,输了游戏各种游戏状态rady runningpaused lose 以上状态是通过:void setMode(int newMode)函数实现。
如何实现画出小方块:参看:/blog/206706public class DrawView extends View {private final int mTileSize = 12;private final String TAG="DEMO";private Paint pa = new Paint();private Bitmap mTileArray;void loadImage(){Resources r = this.getContext().getResources();Drawable tile = r.getDrawable(R.drawable.redstar);Bitmap bitmap = Bitmap.createBitmap(mTileSize, mTileSize, Bitmap.Config.ARGB_8888);Canvas canvas = new Canvas(bitmap);tile.setBounds(0, 0, mTileSize, mTileSize);tile.draw(canvas);mTileArray = bitmap;}public DrawView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle);// TODO Auto-generated constructor stubloadImage();x = 10;y = 10;Log.i(TAG, "DrawView 2");}//如果没有这段代码,大家可以试一下,改用上面的代码,程序能否通过。
public DrawView(Context context, AttributeSet attrs) {super(context, attrs);// TODO Auto-generated constructor stubloadImage();Log.i(TAG, "DrawView 3");}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);Log.i(TAG, "onDraw 1");canvas.drawBitmap(mTileArray, x, y, pa);}}通过上面的文章可以画出小方块,但注意到SnakeView一共有两构造函数,那个函数才真正起作用呢?●public SnakeView(Context context, AttributeSet attrs)●public SnakeView(Context context, AttributeSet attrs, int defStyle)通过加log的方式,判断是第一个构造函数起作用。