基于51单片机的双人对战小游戏的实现

发布者:SereneSunset最新更新时间:2015-06-24 来源: 51hei关键字:51单片机  双人对战小游戏 手机看文章 扫描二维码
随时随地手机看文章
#include
unsigned char position1=1;//position一共有3种状态,0代表最边上,1代表初始位置,2代表最前的位置
unsigned char position2=1;//position一共有3种状态,0代表最边上,1代表初始位置,2代表最前的位置
unsigned char fist1=0;//1没有出拳
unsigned char fist2=0;//2没有出拳
unsigned char leg1=0;//1没有出脚
unsigned char leg2=0;//2没有出脚

unsigned char count_back1=0;
unsigned char count_back2=0;

unsigned char count_forth1=0;
unsigned char count_forth2=0;

unsigned char time0_count=0;
unsigned char time1_count=0;

unsigned char blood1=7;
unsigned char blood2=7;

unsigned char buff1[16]={0x00,0x18,0x24,0x24,0x18,0x18,0x7E,0x66,//右边小人的初始形态
                                                0x66,0x24,0x3C,0x24,0x24,0x24,0x24,0x00};

unsigned char buff2[16]={0x00,0x18,0x24,0x24,0x18,0x18,0x7E,0x66,//右边小人的初始形态
                                                0x66,0x24,0x3C,0x24,0x24,0x24,0x24,0x00};

//定义两名选手的操作键

//选手1
#define S11 P1_0//向前
#define S12 P1_1//后退
#define S13 P1_2//出拳
#define S14 P1_3//出腿

//选手2
#define S21 P1_4//向前
#define S22 P1_5//向后
#define S23 P1_6//出出
#define S24 P1_7//腿拳

//两个选手的led点阵行扫描使能端
#define A_1 P0_0
#define B_1 P0_1
#define C_1 P0_2
#define D_1 P0_3


//两个选手的2个595使能端
#define SCLK P2_0
#define SI P2_1
#define RCLK P2_2


//当按下S1时 开始游戏,游戏结束时显示哪方获胜,然后按下S2键后重新开始新一轮游戏
#define S1 P2_6
#define S2 P2_7

//第一个人的74HC154区域行选
#define NUMLED1OPEN(); {D_1=0;C_1=0;B_1=0;A_1=0;};
#define NUMLED2OPEN(); {D_1=0;C_1=0;B_1=0;A_1=1;};
#define NUMLED3OPEN(); {D_1=0;C_1=0;B_1=1;A_1=0;};
#define NUMLED4OPEN(); {D_1=0;C_1=0;B_1=1;A_1=1;};
#define NUMLED5OPEN(); {D_1=0;C_1=1;B_1=0;A_1=0;};
#define NUMLED6OPEN(); {D_1=0;C_1=1;B_1=0;A_1=1;};
#define NUMLED7OPEN(); {D_1=0;C_1=1;B_1=1;A_1=0;};
#define NUMLED8OPEN(); {D_1=0;C_1=1;B_1=1;A_1=1;};
#define NUMLED9OPEN(); {D_1=1;C_1=0;B_1=0;A_1=0;};
#define NUMLED10OPEN(); {D_1=1;C_1=0;B_1=0;A_1=1;};
#define NUMLED11OPEN(); {D_1=1;C_1=0;B_1=1;A_1=0;};
#define NUMLED12OPEN(); {D_1=1;C_1=0;B_1=1;A_1=1;};
#define NUMLED13OPEN(); {D_1=1;C_1=1;B_1=0;A_1=0;};
#define NUMLED14OPEN(); {D_1=1;C_1=1;B_1=0;A_1=1;};
#define NUMLED15OPEN(); {D_1=1;C_1=1;B_1=1;A_1=0;};
#define NUMLED16OPEN(); {D_1=1;C_1=1;B_1=1;A_1=1;};

//0是第一个选手的索引表的开始 80是第二个选手开始在表中的位置
#define START1 0
#define START2 80
#define INIT 16//第一个选手从的初始状态在中间 为16
#define JUMP_UP_AND_BACK1 48//向后跳起的缓冲动作的位置
#define JUMP_UP_AND_BACK2 64//向后跳起的缓冲动作的位置
#define BACK 0//在最边后面的状态的位置
#define FORTH 32//在最前面的状态的位置

#define GO 0//游戏的开始画面 然后按S1开始游戏
//#define KO 32
#define P1_WIN 64//显示P1胜利在索引表中的位置
#define P2_WIN 96//显示P2胜利在索引表中的位置

//图像表
//人物的各种形态和位置
unsigned char code role_action[]=
{
0x00,0x0C,0x12,0x12,0x0C,0x0C,0x3F,0x33,//左边小人后退一步的状态0
0x33,0x12,0x1E,0x12,0x12,0x12,0x12,0x00,

0x00,0x18,0x24,0x24,0x18,0x18,0x7E,0x66,//左边小人的初始形态16
0x66,0x24,0x3C,0x24,0x24,0x24,0x24,0x00,

0x00,0x30,0x48,0x48,0x30,0x30,0xFC,0xCC,//左边小人前进一步的状态32
0xCC,0x48,0x78,0x48,0x48,0x48,0x48,0x00,

0x18,0x24,0x24,0x18,0x18,0x66,0x66,0x65,//左边小人向右后方向跳起的动作1 48
0x24,0x3C,0x24,0x12,0x12,0x12,0x00,0x00,

0x0C,0x12,0x12,0x0C,0x0C,0x33,0x33,0x53,//左边小人向右后方向跳起的动作2 64
0x12,0x1E,0x12,0x24,0x24,0x24,0x00,0x00,

0x00,0x30,0x48,0x48,0x30,0x30,0xCC,0xCC,//右边小人后退一步的动作80
0xCC,0x48,0x78,0x48,0x48,0x48,0x48,0x00,

0x00,0x18,0x24,0x24,0x18,0x18,0x7E,0x66,//左边小人的初始形态96
0x66,0x24,0x3C,0x24,0x24,0x24,0x24,0x00,

0x00,0x0C,0x12,0x12,0x0C,0x0C,0x33,0x33,//右边小人前进一步的状态112
0x33,0x12,0x1E,0x12,0x12,0x12,0x12,0x00,

0x18,0x24,0x24,0x18,0x18,0x66,0x66,0xA6,//右边小人向左后方向跳起的动作1 128
0x24,0x3C,0x24,0x48,0x48,0x48,0x00,0x00,

0x30,0x48,0x48,0x30,0x30,0xCC,0xCC,0xCA,//右边小人向左后方向跳起的动作2 144
0x48,0x78,0x48,0x24,0x24,0x24,0x00,0x00


};

//开机画面和结束时显示哪方胜利的索引表
unsigned char code welecome_and_end[]=
{
0x00,0x00,0x00,0x04,0xF9,0xF4,0xF9,0xF4,0x00,0x04,0xF9,0xF4,0xF9,0xF4,0x00,0x00,
0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//GO!!!  0

0x00,0x00,0x22,0x38,0x24,0x44,0x28,0x44,0x30,0x44,0x28,0x44,0x24,0x44,0x22,0x44,
0x22,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x92,0x49,0x45,0x14,0x28,0xA2,0x92,0x49,//KO 32

0x00,0x00,0x00,0x00,0x00,0x00,0x25,0x12,0x51,0x13,0x55,0x12,0x55,0x52,0x54,0xA7,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//P1 WIN 64

0x00,0x00,0x00,0x00,0x00,0x00,0x4A,0x24,0xA2,0x2A,0xAA,0x24,0xAA,0xA2,0xA9,0x4E,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00//P2 WIN  96

};

void delayu(unsigned int time);//延时函数 延时0.1ms

void delay(unsigned int time);//延时函数 延时1ms

void NUMLEDOPEN(int i);//74HC154进行行选择,第i行


void dat_in(unsigned char dat);//将8为数据从597传送过去


void display_one_page();//先加载各方“血”的状态,并显示一张图片,显示人的状态和血的状态
void display_scene(int scene);//显示开机画面和胜负画面的函数
void change_buffer_to1(int position);//修改1的图像状态缓冲 从人物索引表的第position个8位数个开始显示
void change_buffer_to2(int position);//修改2的图像状态缓冲 从人物索引表的第position个8位数个开始显示
void action_back1();//第1个人向后一步 并将position减1 直到它不能后退
void action_back2();//第2个人向后一步 并将position减1 直到它不能后退
void action_forth1();//第1个人向前一步 并将position加1 直到它不能后退
void action_forth2();//第2个人向前一步 并将position加1 直到它不能后退
void fist_change_buff1();//由于1出拳对画面的改动 要调用change_buff1_to_bit(int pos)和change_buff1_to_bit_low(int pos)函数
void leg_change_buff1();//由于1出腿对画面的改动        要调用change_buff1_to_bit(int pos)和change_buff1_to_bit_low(int pos)函数
void fist_change_buff2();//由于2出拳对画面的改动 要调用change_buff1_to_bit(int pos)和change_buff1_to_bit_low(int pos)函数
void leg_change_buff2();//由于2出腿对画面的改动 要调用change_buff1_to_bit(int pos)和change_buff1_to_bit_low(int pos)函数
void change_buff1_to_bit(int pos); //将特定某一位置一
void change_buff2_to_bit(int pos);//将特定某一位置一
void change_buff1_to_bit_low(int pos);//将特定某一位置0
void change_buff2_to_bit_low(int pos);//将特定某一位置0
void action_fist1();//第1个人出拳 并处理减血情况
void action_fist2();//第2个人出拳 并处理减血情况
void action_leg1();//第1个人出腿 并处理减血情况
void action_leg2();//第2个人出腿 并处理减血情况
void scan_key();
//这个是函数的主体部分 分别扫描并处理向后退 向前走 出拳 出腿的动作 当出拳和出腿的时候 开启定时器
//这300ms内记录是否有对方出拳出腿的动作 并按照先扫描向后退 后扫描向前进的顺序 扫描一遍 并处理 如果没有这两个动作 直接返回调用出拳
//否则处理后再出拳 出脚的道理一致
void init_interrupt();//中断位的设置
//开启定两个时器中断 16位模式
void shed_blood1();
//记录流血的数字
void shed_blood2();

void main()
{
        int i;
        while(1)
        {
                if(S1==0)
                {
                        delay(1);
                        if(S1==0)
                        {
                                for(i=0;i0)
        {
        if(position1==2)
        {
                i=15;
                change_buffer_to1(START1+JUMP_UP_AND_BACK2);
                while(i--)
                        display_one_page();
                i=5;
                change_buffer_to1(START1+INIT);
                while(i--)
                        display_one_page();
        }
        else if(position1==1)
        {
                i=15;
                change_buffer_to1(START1+JUMP_UP_AND_BACK2);
                while(i--)
                        display_one_page();
                i=5;
                change_buffer_to1(START1+BACK);
                while(i--)
                        display_one_page();
        }
        position1--;
        }
}

void action_back2()//第2个人向后一步
{
//先显示向后跳起的动作 再显示后退的状态
        int i;
       
        if(position2>0)
        {
        if(position2==2)
        {
                i=15;
                change_buffer_to2(START1+JUMP_UP_AND_BACK1);
                while(i--)
                        display_one_page();
                i=5;
                change_buffer_to2(START2+INIT);
                while(i--)
                        display_one_page();
        }
        else if(position2==1)
        {
                i=15;
                change_buffer_to2(START2+JUMP_UP_AND_BACK2);
                while(i--)
                        display_one_page();
                i=5;
                change_buffer_to2(START2+BACK);
                while(i--)
                        display_one_page();
        }
        position2--;
        }
}

void action_forth1()//第1个人向前一步
{

        int i;

        if(position1<2)
        {
                if(position1==1)
                {
                        i=10;
                        change_buffer_to1(START1+FORTH);
                        while(i--)
                                display_one_page();
                }
                else if(position1==0)
                {
                        i=10;
                        change_buffer_to1(START1+INIT);
                        while(i--)
                                display_one_page();
                }
                position1++;
        }
       
}

void action_forth2()//第2个人向前一步
{
//直接显示向前一步的状态
int i;

        if(position2<2)
        {
                if(position2==1)
                {
                        i=10;
                        change_buffer_to2(START2+FORTH);
                        while(i--)
                                display_one_page();
                }
                else if(position2==0)
                {
                        i=10;
                        change_buffer_to2(START1+INIT);
                        while(i--)
                                display_one_page();
                }
                position2++;
        }
}

void change_buff1_to_bit(int pos)
{
        int p1=pos/8;
        int p2=pos%8;
        unsigned char flag=0x01;
        flag=flag<0)
                                blood1--;
                }
        }
        else if(position2==2)
        {
                if(position1>0)
                {
               
                        if(blood1>0)
                                blood1--;
                }
        }
}

void shed_blood2()
{
        if(position1==1)
        {
                if(position2==2)
                {
                        if(blood2>0)
                                blood2--;
                }
        }
        else if(position1==2)
        {
                if(position2>0)
                {
               
                        if(blood2>0)
                                blood2--;
                }
        }
}


void handle1() interrupt 1
{

        EA=0;
       
        TH0=63536/256;//2ms一次定时器中断
        TL0=63536%256;
        time0_count++;
        if(time0_count==200)
        {
                time0_count=0;
                TR0=0;
                if(count_back2==1)
                {
                        count_back2=0;
                        action_back2();
                }
                else if(count_forth2==1)
                {
                        count_forth2=0;
                        action_forth2();
                }
        }
        EA=1;
}

void handle2() interrupt 3
{

        EA=0;
       
        TH1=63536/256;//2ms一次定时器中断
        TL1=63536%256;
        time1_count++;
        if(time1_count==200)
        {
                time1_count=0;
                TR1=0;
                if(count_back1==1)
                {
                        count_back1=0;
                        action_back1();
                }
                else if(count_forth1==1)
                {
                        count_forth1=0;
                        action_forth1();
                }
        }
        EA=1;       
}
关键字:51单片机  双人对战小游戏 引用地址:基于51单片机的双人对战小游戏的实现

上一篇:51单片机学习之1-锁存器驱动led灯
下一篇:基于51单片机驱动LCD1602液晶显示thb6064ah细分64

推荐阅读最新更新时间:2024-03-16 14:04

C51单片机数字时钟系统原理解析
有关的硬件原理图: c程序: //温馨提示: /*程序还没有调试完成,实际电路板调节时间时时-分-秒都会有闪烁现象,其实我是不知道的,why,也求解释 #include //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义 #include //与_nop_有关 sbit duan=P2^2; //定义锁存使能端口 段锁存 sbit wei=P2^3; // 位锁存 sbit key1 = P1^1; sbit key2 = P1^2; sbit key3 = P1^3; sbit key4 = P1^4; unsigned char code duanma[10]={0x3f,0x06,0x5b,0x4f,0
[单片机]
C<font color='red'>51单片机</font>数字时钟系统原理解析
51单片机学习:LED点阵实验(显示数字)
实验名称:LED点阵实验(显示数字) 接线说明: 实验现象:下载程序后,8*8LED点阵显示数字0 注意事项:LED点阵旁的J24黄色跳线帽短接到GND一端 ***************************************************************************************/ #include reg51.h typedef unsigned int u16; //对系统默认数据类型进行重定义 typedef unsigned char u8; //定义74HC595控制管脚 sbit SRCLK=P3^6; //移位寄存器时钟输入 sbit RCLK=P3^5; //存
[单片机]
AT89C51单片机驱动128x64液晶显示C语言
/******************************************************************* AT89C51单片机驱动128x64液晶显示C语言 ****************************************************************/ #include AT89x51.h #define uchar unsigned char /***************************************** 电路连接 P1------DB0~DB7 P2.0------RS P2.1------RW P2.2------E *******
[单片机]
51单片机时钟精度误差的解决
前几天用STC89C52单片机制作了一个电子时钟,经过一段时间的实验,发现时间精度存在误差,一分钟慢4秒左右。 这可了不得,十分钟就要慢40秒,一天下来不得慢半96分钟!!! 这个单片机晶振频率为11.0592mhz,和大部分时钟的晶振频率相同,应该没有问题。 后天考虑到源代码: 在定时器中断函数里: void t0(void) interrupt 1 using 0 { tcount++; if(tcount==4000) {tcount=0; second++; if(second==60) {second=0; minute++; if(minut
[单片机]
51单片机-模拟倒车雷达报警
1.题目要求 我们在第九章第3讲的例程基础上,实现用超声波模块模拟倒车雷达报警的功能,当障碍物距离超声波模块小于等于10cm左右我们就用蜂鸣器鸣叫产生报警,大于10cm就不报警。代码上添加的程序量比较少,我们只是把定时时间改为200微秒好使蜂鸣器鸣叫的比较尖锐。 2.main.c测试代码 #include reg52.h #include function.h //详见第六章第8讲 #include timer.h //详见第八章第11讲 #include intrins.h sbit TRIG = P2^0; sbit ECHO = P2^1; u8 FLAG=0,BEEP_FLAG=0; void d
[单片机]
实例源码2---基于51单片机的摇摇棒制作
#include #define uchar unsigned char #define uint unsigned int sbit key = P3^0;//定义切换画面开关 uchar Key_num;//定义按键次数 uchar Int0_num=0;//定义中断次数 uchar Direction;//定义摇动方向(从左到右) uchar code Embed ={ 0x40,0x00,0x20,0x00,0xd0,0x3f,0x4c,0x40,0x43,0x40,0x44,0x42,0x48,0x44,0xd8,0x43, 0x30,0x78,0x10,0x00,0x00,0x00,0xfc,0x07,0x00,0
[单片机]
基于51单片机设计的用电故障控制系统
1 引言   对于电网短路和线路故障检测保护已有不少研究。市面上的电器短路、过载、超压的保护器功能单一。容易损坏,没用提示功能,不够人性化。但随人们生活水平的不断提高。用电设备也不断增加,产生了肓目用电现象。这给人们造成极大的安全隐患。其中危害性最大的用电故障有三种:输入电压过高、室内线路严重过载、用电器短路。本文设计的单片机AT89C5l用电故障控制系统的目的就是为了防止这三种故障带来的危害。   2 硬件的组成   单片机用电故障控制系统的硬件分别是:由降压变压器、2个相瓦串联的感应线圈、升压变JK器、电磁开关、5V稳压电源、超压过流信号获取比较电路、可编程接门扩展芯片8255、HD44780字符液晶显示模块、ISD26
[单片机]
基于<font color='red'>51单片机</font>设计的用电故障控制系统
51单片机控制步进电机硬件连接部分
1、概要: 本案例讲解的内容是51单片机控制步进电机硬件连接部分。后续会分别讲解单片机程序,S曲线加减速方法,上位机等相关内容 2、功能原理图: 2.1、51单片机: ①输出脉冲到TB6600驱动器PUL端口,从而控制步进电机转动 ②控制TB6600驱动器ENA端口,从而控制步进电机使能 ③控制TB6600驱动器DIR端口,从而控制步进电机转动方向 2.2、步进电机: ①提供机械动力 2.3、稳压电源: ①为步进电机提供电源 2.4、TB6600驱动器: ①二相四线步进电机专用驱动器 3、实物图: ** ①** 、51****单片机控制板一个 ** ②** 、二相四线步进电机一个 ** ③** 、稳压电源一个 ** ④** 、
[单片机]
<font color='red'>51单片机</font>控制步进电机硬件连接部分
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved