c语言制作一个简单的打字游戏(落下一个字母按相应字母消去,记录分数)

c语言制作一个简单的打字游戏(落下一个字母按相应字母消去,记录分数),第1张

游戏常量参数自行修改(字母的列数,下落最大高度,下落速度等)。

程序功能:(随机生成字母,下落,并检查按键,计分)

多线程按键检查采用新的线程与主线程同步。

独立速度:每个字母下落速度都是随机且不相同。

玩法:按键区分大小写,落到底部或被玩家按中,下落中的字母就会消失,并在该列顶部创建新的字母下落,按中1次记1分。

注意:由于字母都是随机的,如果同时下落的字母很多,可能会有重复字母出现,如果按键对应了多个同样的字母,这些字母会删掉并新建,也就是说出现按中一次记多分,说明有多个重复字母,不是BUG!

#include <stdio.h>

#include <stdlib.h>

#include <malloc.h>

#include <conio.h>

#include <time.h>

#include <windows.h>

#define W 30//宽度

#define H 20//高度

#define MinSPEED 50//最慢下降速度(周期,数字越小越快)

#define MAXSPEED 5//最快下降速度

int score=0//总分

typedef struct letter

{

     int ascii// 字母ASCII码

     int hIndex//对应打印数组行下标

     int wIndex//对应打印数组列下标

     int cnt//周期计数,当cnt==speed,hIndex++并且cnt重新置0

     int speed//下降速度

     int key//0表示没有被按中,1表示被按中

     struct letter *next

}LETR

void meError(void *p)//内存申请失败

LETR *newLETR(LETR *letrHead,LETR*letrTail,int wIndex)//产生一个新的字母,并添加到链表,返回尾节点

LETR* delLETR(LETR *letrHead,LETR*letrTail,int wIndex)//删除列下标的字母节点,返回新的尾节点

LETR *init(LETR *letrHead)//初始化一组字母,返回链表尾节点

LETR *showList(LETR *letrHead,LETR*letrTail)//显示列表并检查,发现到底或被按键按中的字母删除并新建新的字母,返回新的尾节点

void runLetter(LETR *letrHead)//所有字母一周期计数

DWORD WINAPI checkKey(LPVOID lpParameter)//新线程

int main()

{

    int i

    LETR *letrHead=NULL,*letrTail=NULL

    letrHead=(LETR *)malloc(sizeof(LETR))

    meError(letrHead)

    letrHead->next=NULL

    srand(time(NULL))

    letrTail=init(letrHead)

    CreateThread(NULL,0,checkKey,letrHead,0,NULL)

    letrTail=showList(letrHead,letrTail)

    while(1)

    {

        system("cls")

        printf("总分:%d\n",score)

        for(i=0i<Wi++)

            printf("-")

        printf("\n")

        runLetter(letrHead)

        letrTail=showList(letrHead,letrTail)

        for(i=0i<Wi++)

            printf("-")

        printf("\n")

    }

    return 0

}

DWORD WINAPI checkKey(LPVOID lpParameter)

{

char c

LETR *letrHead=NULL

while(1)

    {

        letrHead=(LETR *)lpParameter

        c=getch()

        while(letrHead->next)

        {

            if(c==letrHead->next->ascii)

                letrHead->next->key=1,score++//按键标识置1,考虑可能有多个相同随机字母,故用标识,在显示函数统一删除并新建

            letrHead=letrHead->next

        }

    }

return 0

}

void runLetter(LETR *letrHead)//所有字母一周期计数

{

    while(letrHead->next)

    {

        if(letrHead->cnt<letrHead->speed)

            letrHead->cnt++

        else

            (letrHead->next->hIndex)++,letrHead->cnt=0

        letrHead=letrHead->next

    }

}

LETR *showList(LETR *letrHead,LETR*letrTail)//显示列表并检查,发现到底或被按键按中的字母删除并新建新的字母,返回新的尾节点

{

    int i,j,wIndex

    char sp[H][W]

    LETR *head=letrHead

    for(i=0i<Hi++)

        for(j=0j<Wj++)

            sp[i][j]=' '

    while(letrHead->next)

    {

        if(letrHead->next->hIndex>H-1 || letrHead->next->key==1)//到底或者被按中就删除并新建,重新循环

        {

            wIndex=letrHead->next->wIndex

            letrTail=delLETR(head,letrTail,wIndex)

            letrTail=newLETR(head,letrTail,wIndex)

            letrHead=head

        }

        else

            sp[letrHead->next->hIndex][letrHead->next->wIndex]=letrHead->next->ascii

        letrHead=letrHead->next

    }

    for(i=0i<Hi++,printf("\n"))

        for(j=0j<Wj++)

            printf("%c",sp[i][j])

    return letrTail

}

LETR *init(LETR *letrHead)//初始化一组字母,返回链表尾节点

{

    int i

    LETR*letrTail=NULL

    for(i=0i<Wi++)

        letrTail=newLETR(letrHead,letrTail,i)

    return letrTail

}

LETR *newLETR(LETR *letrHead,LETR*letrTail,int wIndex)//在列下标wIndex首行,产生一个新的字母,并添加到链表,返回尾节点

{

    int n

    LETR *leterNEW=(LETR *)malloc(sizeof(LETR))

    meError(leterNEW)

    leterNEW->next=NULL

    n=rand()%2

    if(n)//随机大小写

        leterNEW->ascii=rand()%26+65//随机一个大写字母

    else

        leterNEW->ascii=rand()%26+97//随机一个小写字母

    leterNEW->hIndex=0

    leterNEW->wIndex=wIndex

    leterNEW->cnt=0

    leterNEW->speed=rand()%(MinSPEED-MAXSPEED)+1+MAXSPEED

    leterNEW->key=0

    if(letrHead->next==NULL)

        letrHead->next=leterNEW

    else

        letrTail->next=leterNEW

    letrTail=leterNEW

    return letrTail

}

LETR* delLETR(LETR *letrHead,LETR*letrTail,int wIndex)//删除列下标的字母节点,返回新的尾节点

{

    LETR *lhead=letrHead,*letrDel=NULL

    while(letrHead->next)

    {

        if(letrHead->next->wIndex==wIndex)

        {

            letrDel=letrHead->next

            letrHead->next=letrHead->next->next

            free(letrDel)

            break

        }

        letrHead=letrHead->next

    }

    letrHead=lhead

    while(letrHead->next)//重置尾节点

        letrHead=letrHead->next

    return letrHead

}

void meError(void *p)//内存申请失败

{

    if(p==NULL)

    {

        printf("\n异常:内存申请失败!回车结束程序!\n")

        while(getch()!='\r')

        exit(0)

    }

}

很好写的

显示加判断

org 00h

main:

mov p1,#00h

mov r1,#00h

a1:call dis

jb p3.2, j1

jb p3.3,j2

jb p3.4,j3

jmp a1

dis:

mov a,r1

mov b,#10

div ab

mov p1,a

setb p2.0

call yanshi

mov p1,b

clr p2.0

call yanshi

ret

ji:call yanshi

jnb p3.2,a1

inc r1

ret

j2:call yanshi

jnb p3.3,a1

inc r1

inc r1

ret

j3:call yanshi

jnb p3.4,a1

subb r1 ,#01h

ret

yanshi :

延时自己写好了

ret

end

这个问题早已完全解决,试试我给你改的程序

void display(uchar fen,uchar miao,uchar a_fen,uchar b_fen) //数码管显示子函数

{

dula=1

P0=miaotable[a_shi]

dula=0

P0=0x00

wela=1

P0=0x10

wela=0

delay(3)

}

void keyscan()//键盘扫描子函数

{

if(shezhi==0) //计数按下"设置"键的次

flag=1

if((shezhi==1)&&(flag==1))

{

shezhinum++

flag=0

if(shezhinum==5)//按第五次"设置"时归零

shezhinum=0

}

}

void main() //主函数

{

int flag=0

while(1)

{

display(fennum,miaonum,a_num,b_num)

keyscan()

}

}

void T0_time() interrupt 1 //中断函数

{

TH0=(65536-50000)/256

TL0=(65536-50000)%256

numt0++

if(fennum!=0||miaonum!=0)

{

if(numt0==20)

{

numt0=0

miaonum--

if(miaonum==-1)

{

fennum-=1

miaonum=59

}

}

}

else

{

TR0=0

}

}

}


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/11843202.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-19
下一篇 2023-05-19

发表评论

登录后才能评论

评论列表(0条)

保存