C语言实现俄罗斯方块源代码
作者:name_文强 发布时间:2023-02-28 13:16:45
标签:C语言,俄罗斯方块
本文实例为大家分享了C语言实现俄罗斯方块的具体代码,供大家参考,具体内容如下
GitHub:【C语言】实现俄罗斯方块源代码
Head.h
#ifndef _HEAD_H_
#define _HEAD_H_
#include<graphics.h>
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<time.h>
#include<string.h>
#define _CRT_SECURE_NO_WARNINGS 1
//界面的相关的参数
#define WALL_SQUARE_WIDTH 10 //围墙方块的宽度
#define xWALL_SQUARE_NUM 30 //x轴方向的方块的数目
#define yWALL_SQUARE_WIDTH 46 //y轴方向的方块的数目
#define GAME_WALL_WIDTH (WALL_SQUARE_WIDTH*xWALL_SQUARE_NUM) //游戏区域的宽度 300
#define GAME_WALL_HTGH (WALL_SQUARE_WIDTH*yWALL_SQUARE_WIDTH) //游戏区域的高度 460
#define WINDOW_WIDTH 480 // 游戏总窗口宽度 480
#define WINDOW_HIGH 460 // 游戏总窗口高度 460
//定义俄罗斯方块的相关参数
#define ROCK_SQUARE_WIDTH (2*WALL_SQUARE_WIDTH) //俄罗斯方块的大小是围墙的两倍 20
#define xROCK_SQUARE_NUM ((GAME_WALL_WIDTH -20)/ROCK_SQUARE_WIDTH) // 游戏区x轴放的方块数目:14
#define yROCK_SQUARE_NUM ((GAME_WALL_HTGH -20)/ROCK_SQUARE_WIDTH) // 游戏区y轴放的方块数目:22
//定义移动方块的相关操作
#define DIRECT_UP 3
#define DIRECT_DOWN 2
#define DIRECT_LEFT -1
#define DIRECT_RIGHT 1
/*数据结构-线性表(结构体数组)*/
typedef struct ROCK
{
//用来表示方块的形状(每一个字节是8位,用每4位表示方块中的一行)
unsigned short rockShapeBits;
int nextRockIndex; //下一个方块,在数组中的下标
} RockType;
//方块在图形窗口中的位置(即定位4*4大块的左上角坐标)
typedef struct LOCATE
{
int left;
int top;
} RockLocation_t;
//全局变量-游戏板的状态描述(即表示当前界面哪些位置有方块)
//0表示没有,1表示有(多加了两行和两列,形成一个围墙,便于判断方块是否能够移动)
int game_board[yROCK_SQUARE_NUM + 2][xROCK_SQUARE_NUM + 2] = { 0 };
int game_socres = 0; //全局分数
// 把俄罗斯方块的19种类放到数组中
int rockTypeNum = 19;
RockType RockArray[19] = { (0, 0) };
//预览区的方块的位置
RockLocation_t preRockLocation = {GAME_WALL_WIDTH+70,70};
//每次生成初始化方块的位置
RockLocation_t initRockLocation = { (WALL_SQUARE_WIDTH + 100), WALL_SQUARE_WIDTH };
//分数显示的位置
//各个文件中的函数
// 画出界面以及画出方块Draw.h中
void DrawGameWindow();
void DisplayRock(int rockIdx, RockLocation_t* LocatePtr, bool displayed);
//初始化Init源文件
void InitGame();
//game.h
void PlayGame();
bool IsGameOver();
#endif
Draw.h
#include"Head.h"
//画出游戏界面
void DrawGameWindow()
{
//先画出围墙
setcolor(BLUE);
setlinestyle(PS_SOLID,NULL,0);
setfillcolor(BLUE);
//画出上下围墙
for (int x = WALL_SQUARE_WIDTH; x <= GAME_WALL_WIDTH; x += WALL_SQUARE_WIDTH)
{
fillrectangle(x - WALL_SQUARE_WIDTH, 0, x, WALL_SQUARE_WIDTH); //上
fillrectangle(x - WALL_SQUARE_WIDTH, GAME_WALL_HTGH - WALL_SQUARE_WIDTH, x, GAME_WALL_HTGH);//下
}
//画出左右围墙
for (int y = WALL_SQUARE_WIDTH; y <= GAME_WALL_HTGH; y += WALL_SQUARE_WIDTH)
{
fillrectangle(0, y, WALL_SQUARE_WIDTH, y + WALL_SQUARE_WIDTH);//左
fillrectangle(GAME_WALL_WIDTH - WALL_SQUARE_WIDTH, y, GAME_WALL_WIDTH, y + WALL_SQUARE_WIDTH);//右
}
//画出右边统计分数及相关东西
//画出分割线
setcolor(WHITE);
setlinestyle(PS_DASH,2);
line(GAME_WALL_WIDTH + 20, 0, GAME_WALL_WIDTH + 20, GAME_WALL_HTGH);
//设置字体
LOGFONT font;
gettextstyle(&font);
settextstyle(18, 0, _T("宋体"));
font.lfQuality = ANTIALIASED_QUALITY;//设置输出效果为抗锯齿
//1显示预览形状
outtextxy(GAME_WALL_WIDTH + 80, 30, _T("预览"));
outtextxy(GAME_WALL_WIDTH + 80, 170, _T("分数"));
outtextxy(GAME_WALL_WIDTH + 65, 250, _T("操作说明"));
outtextxy(GAME_WALL_WIDTH + 40, 290, _T("w a s d控制方向"));
outtextxy(GAME_WALL_WIDTH + 40, 335, _T("空格 暂停"));
//显示分数
setcolor(RED);
outtextxy(GAME_WALL_WIDTH + 90, 200, '0');
}
//在游戏区显示编号为rockIdx的方块
void DisplayRock(int rockIdx, RockLocation_t* LocatePtr, bool displayed)
{
int color;//方块的填充颜色
int lineColor = WHITE;//线的颜色
int boardFalg = 0;
int xRock = 0;
int yRock = 0;
unsigned short rockCode = RockArray[rockIdx].rockShapeBits;
//如果displayed为true的话,将方块块颜色设置为white,game_board对应的位置设置为1;
//如果displayed为false的话,将方块块颜色设置为black,game_board对应的位置设置为0;
displayed ? (color = RED, boardFalg = 1) : (color = BLACK,lineColor = BLACK, boardFalg = 0);
setcolor(lineColor);
setfillcolor(color);
setlinestyle(PS_SOLID);//设置为实线,
xRock = LocatePtr->left;
yRock = LocatePtr->top;
int count = 0;//每4个换行,记录坐标偏移量
unsigned short mask = 1;
for (int i = 1; i <= 16; ++i)
{
mask = 1 << (16 - i);
if ((rockCode & mask) != 0) //如果不为0的话,就画出小方块
{
fillrectangle(xRock , yRock, xRock + ROCK_SQUARE_WIDTH, yRock + ROCK_SQUARE_WIDTH);
}
if (i % 4 == 0) //换行
{
yRock = yRock + ROCK_SQUARE_WIDTH;
xRock = xRock = LocatePtr->left;
}
else
{
xRock += ROCK_SQUARE_WIDTH;
}
}
}
Init.h
#include"Head.h"
static void ShapeStrToBit(unsigned char *rockShapeStr, unsigned short& rockShapeBit);
static void ReadRcok();
void InitGame()
{
//把全局游戏游戏版初始化,边界初始化为1
for (int i = 0; i < xROCK_SQUARE_NUM + 2; i++)
{
game_board[0][i] = 1; //上边界
game_board[yROCK_SQUARE_NUM + 1][i] = 1; //下边界
}
for (int i = 0; i < yROCK_SQUARE_NUM + 2; i++)
{
game_board[i][0] = 1 ; //左边界
game_board[i][xROCK_SQUARE_NUM + 1] = 1; //右边界
}
//读取俄罗斯方块
ReadRcok();
}
//从文件中读取方块的形状存储到rockArray中
void ReadRcok()
{
FILE* fp = fopen("RockShape.ini","r");
if (NULL == fp)
{
printf("打开文件失败\n");
return;
}
unsigned char readBuf[1024]; //fp读取到字符串readbuf中
unsigned short rockShapeBit = 0;//存放方块形状,占16比特位
unsigned char rockShapeStr[16];//存放方块字符串
int ShapeStrIdx = 0;
int rockNum = 0;//统计方块的个数以及存放方块数组RockArray的下标
int rocknext = 0;//方块数组中下一个形状
int rockShapeStart = 0;//同一类型的形状
while (true)
{
size_t readSize = fread(readBuf, 1, 1024, fp);
if (readSize == 0)
break;
//处理readbuf
for (size_t idx = 0; idx < readSize; ++idx)
{
//将字符存放到rockShapeStr中
while (ShapeStrIdx < 16 && idx < readSize)
{
if (readBuf[idx] == '@' || readBuf[idx] == '#')
{
rockShapeStr[ShapeStrIdx] = (unsigned char)readBuf[idx];
++ShapeStrIdx;
}
++idx; //可能idx == readSize了
if (readBuf[idx] == '*')//修改上一次方块的next值
{
idx += 5;
RockArray[--rockNum].nextRockIndex = rockShapeStart;
rockNum++;
rockShapeStart = rockNum;
rocknext = rockShapeStart ;
}
}
//可能没有填满
if (ShapeStrIdx < 16)
{
break;
}
else //填满shapestr
{
ShapeStrIdx = 0;//置0
//将rockShapeStr 转为rockShapeBit
ShapeStrToBit(rockShapeStr, rockShapeBit);
rocknext++;
RockArray[rockNum].rockShapeBits = rockShapeBit;
RockArray[rockNum].nextRockIndex = rocknext;
rockNum++;
}
}
}
fclose(fp);
}
//将从文件中读取的字符串(长度默认为16)转换成 unsigned short
void ShapeStrToBit(unsigned char *rockShapeStr, unsigned short& rockShapeBit)
{
rockShapeBit = 0;
for (size_t idx = 0; idx < 16; ++idx)
{
if (rockShapeStr[idx] == '@') //1
{
rockShapeBit |= (1 << (16 - idx - 1));
}
// #为0 不需要处理
}
}
game.h
#include"Head.h"
#define _CRT_SECURE_NO_WARNINGS 1
bool MoveAble(int rockIndex, RockLocation_t* currentLocatePtr, int f_direction);
void SetGameBoardFlag(int rockIdx, RockLocation_t* curRockLocation);
void UserHitKeyBoard(char userHit, int* RockIndex, RockLocation_t* curRockLocation);
void FullLine();
void UpdateSocres(int scores);
void DelCurLine(int rowIdx);
bool IsGameOver();
void PlayGame()
{
char userHit = 0;//用户敲击键盘
int curRockIndex = 0;//当前方块的rockArray下标
int nextRockIndex = 0;//下次
RockLocation_t curRockLocation;
curRockLocation.left = initRockLocation.left;
curRockLocation.top = initRockLocation.top;
DWORD oldtime = 0;
srand((unsigned int)time(NULL));
curRockIndex = rand() % rockTypeNum;
nextRockIndex = rand() % rockTypeNum;
//画出预览区初始化方块
//在初始位置和预览区显示方块形状
DisplayRock(curRockIndex, &initRockLocation, 1);
DisplayRock(nextRockIndex, &preRockLocation, 1);
bool moveAbled = false;
while (true)
{
//判断当前方块是否落地(判断能否再下移):如果落地,判断是否满行,再判断是否结束游戏, 改变game_board ,画出下次初始化的方块,以及生成新的预览方块
//
moveAbled = MoveAble(curRockIndex, &curRockLocation, DIRECT_DOWN);
if (!moveAbled) //判断是否落地,不能下移表示落地
{
//修改game_board的值
SetGameBoardFlag(curRockIndex, &curRockLocation);
FullLine();
if (IsGameOver())
{
MessageBox(NULL, _T("游戏结束"), _T("GAME OVER"), MB_OK);
exit(0);
}
//为下次生成模块开始准备
DisplayRock(nextRockIndex, &preRockLocation, false);//擦除旧的方块
curRockIndex = nextRockIndex;
nextRockIndex = rand() % rockTypeNum; //生成新的预览方块
DisplayRock(curRockIndex, &initRockLocation, 1);
DisplayRock(nextRockIndex, &preRockLocation, 1);
FlushBatchDraw();
//修改curRockLocation的值
curRockLocation.left = initRockLocation.left;
curRockLocation.top = initRockLocation.top;
}
if (kbhit()) //如果敲击键盘了 就处理按键
{
userHit = getch();
UserHitKeyBoard(userHit, &curRockIndex, &curRockLocation);
}
//没有 就自动下移一个单位 :不能用else,因为可能按键不是上下左右
DWORD newtime = GetTickCount();
if (newtime - oldtime >= (unsigned int)(300) && moveAbled == TRUE)
{
oldtime = newtime;
DisplayRock(curRockIndex, &curRockLocation, false);
curRockLocation.top += ROCK_SQUARE_WIDTH; //下落一格
}
//AutomaticDownMove(curRockIndex, &curRockLocation);
//画出新方块
DisplayRock(curRockIndex, &curRockLocation, 1);
FlushBatchDraw();
Sleep(20);
}
}
//响应键盘命令时间
void UserHitKeyBoard(char userHit, int* RockIndex, RockLocation_t* curRockLocation)
{
switch (userHit)
{
case 'W':
case 'w'://↑
if (MoveAble(RockArray[*RockIndex].nextRockIndex, curRockLocation, DIRECT_UP))
{
DisplayRock(*RockIndex, curRockLocation, false);
*RockIndex = RockArray[*RockIndex].nextRockIndex;
}
break;
case 'S':
case 's'://↓
if (MoveAble(*RockIndex, curRockLocation, DIRECT_DOWN))
{
DisplayRock(*RockIndex, curRockLocation, false);
curRockLocation->top += 2 * (ROCK_SQUARE_WIDTH);
if (!MoveAble(*RockIndex, curRockLocation, DIRECT_DOWN))
{
curRockLocation->top -= ROCK_SQUARE_WIDTH;
}
}
break;
case 'A':
case 'a': //←
if (MoveAble(*RockIndex, curRockLocation, DIRECT_LEFT))
{
DisplayRock(*RockIndex, curRockLocation, false);
curRockLocation->left -= ROCK_SQUARE_WIDTH;
}
break;
case 'D':
case 'd': //→
if (MoveAble(*RockIndex, curRockLocation, DIRECT_RIGHT))
{
DisplayRock(*RockIndex, curRockLocation, FALSE);
curRockLocation->left += ROCK_SQUARE_WIDTH;
}
break;
case ' ': //暂停
while (1)
{
userHit = getch();
if (userHit == ' ')
break;
}
break;
default:
break;
}
}
//判断是否满行,满行消除,然后计算得分
void FullLine()
{
bool linefull = true;
int idx = yROCK_SQUARE_NUM;//从最后一行往上查找 22
int count = 0;
while (count != xROCK_SQUARE_NUM ) //遇到空行 14
{
linefull = true;
count = 0;
for (int i = 1; i <= xROCK_SQUARE_NUM; ++i)
{
if (game_board[idx][i] == 0)
{
linefull = false;
count++;
}
}
if (linefull) //满行,消除当前行,更新分数
{
DelCurLine(idx);
game_socres += 3;
UpdateSocres(game_socres);
idx++;//因为下面要减1
}
idx--;
}
}
void UpdateSocres(int scores)
{
setcolor(RED);
TCHAR s[10];
_stprintf(s, _T("%d"), scores);
outtextxy(GAME_WALL_WIDTH + 90, 200, s);
}
//消除当前行
void DelCurLine(int rowIdx)
{
//擦除当前行
setcolor(BLACK);
setfillcolor(BLACK);
for (int i = 1; i < xROCK_SQUARE_NUM; ++i)
{
fillrectangle(WALL_SQUARE_WIDTH + (i - 1)*ROCK_SQUARE_WIDTH, (rowIdx - 1)*ROCK_SQUARE_WIDTH + WALL_SQUARE_WIDTH,
WALL_SQUARE_WIDTH + i*ROCK_SQUARE_WIDTH, rowIdx*ROCK_SQUARE_WIDTH + WALL_SQUARE_WIDTH);
}
//把上面的向下移
int cnt = 0;
while (cnt != xROCK_SQUARE_NUM) //直到遇到是空行的为止
{
cnt = 0;
for (int i = 1; i <= xROCK_SQUARE_NUM; i++)
{
game_board[rowIdx][i] = game_board[rowIdx - 1][i];
//擦除上面的一行
setcolor(BLACK);
setfillcolor(BLACK);
fillrectangle(WALL_SQUARE_WIDTH + ROCK_SQUARE_WIDTH*i - ROCK_SQUARE_WIDTH ,
WALL_SQUARE_WIDTH + ROCK_SQUARE_WIDTH*(rowIdx - 1) - ROCK_SQUARE_WIDTH ,
WALL_SQUARE_WIDTH + ROCK_SQUARE_WIDTH*i,
WALL_SQUARE_WIDTH + ROCK_SQUARE_WIDTH*(rowIdx - 1));
//显示下面的一行
if (game_board[rowIdx][i] == 1)
{
setcolor(WHITE);
setfillcolor(RED);
fillrectangle(WALL_SQUARE_WIDTH + ROCK_SQUARE_WIDTH*i - ROCK_SQUARE_WIDTH ,
WALL_SQUARE_WIDTH + ROCK_SQUARE_WIDTH*rowIdx - ROCK_SQUARE_WIDTH ,
WALL_SQUARE_WIDTH + ROCK_SQUARE_WIDTH*i,
WALL_SQUARE_WIDTH + ROCK_SQUARE_WIDTH*rowIdx);
}
if (game_board[rowIdx][i] == 0)
cnt++; //统计一行是不是 都是空格
}//for
rowIdx--;
}
}
//是否可以移动方块
bool MoveAble(int rockIndex, RockLocation_t* currentLocatePtr, int f_direction)
{
int mask;
int rockX;
int rockY;
rockX = currentLocatePtr->left;
rockY = currentLocatePtr->top;
mask = (unsigned short)1 << 15;
for (int i = 1; i <= 16; i++)
{
//与掩码相与为1的 即为方块上的点
if ((RockArray[rockIndex].rockShapeBits & mask) != 0)
{
//判断能否移动(即扫描即将移动的位置 是否与设置的围墙有重叠)
//若是向上(即翻滚变形)
if (f_direction == DIRECT_UP)
{
//因为此情况下传入的是下一个方块的形状,故我们直接判断此方块的位置是否已经被占
//判断下一个方块
if (game_board[(rockY - WALL_SQUARE_WIDTH) / ROCK_SQUARE_WIDTH + 1]
[(rockX - WALL_SQUARE_WIDTH) / ROCK_SQUARE_WIDTH + 1] == 1)
return false;
}
//如果是向下方向移动
else if (f_direction == DIRECT_DOWN)
{
if (game_board[(rockY - WALL_SQUARE_WIDTH) / ROCK_SQUARE_WIDTH + 2]
[(rockX - WALL_SQUARE_WIDTH) / ROCK_SQUARE_WIDTH + 1] == 1)
return false;
}
else //如果是左右方向移动
{ //f_direction的DIRECT_LEFT为-1,DIRECT_RIGHT为1,故直接加f_direction即可判断。
if (game_board[(rockY - WALL_SQUARE_WIDTH) / ROCK_SQUARE_WIDTH + 1]
[(rockX - WALL_SQUARE_WIDTH) / ROCK_SQUARE_WIDTH + 1 + f_direction] == 1)
return false;
}
}
//每4次 换行 转到下一行继续
i % 4 == 0 ? (rockY += ROCK_SQUARE_WIDTH, rockX = currentLocatePtr->left)
: rockX += ROCK_SQUARE_WIDTH;
mask >>= 1;
}
return true;
}
//给游戏game_board设置标记表示已经占了
void SetGameBoardFlag(int rockIdx, RockLocation_t* curRockLocation)
{
int mask;
int rockX;
int rockY;
rockX = curRockLocation->left;
rockY = curRockLocation->top;
mask = (unsigned int)1 << 15;
for (int i = 1; i <= 16; i++)
{
//与掩码相与为1的 即为方块上的点
if ((RockArray[rockIdx].rockShapeBits & mask) != 0)
{
game_board[(rockY - WALL_SQUARE_WIDTH) / ROCK_SQUARE_WIDTH + 1]
[(rockX - WALL_SQUARE_WIDTH) / ROCK_SQUARE_WIDTH + 1] = 1;
}
//每4次 换行 转到下一行继续画
i % 4 == 0 ? (rockY += ROCK_SQUARE_WIDTH, rockX = curRockLocation->left)
: rockX += ROCK_SQUARE_WIDTH;
mask >>= 1;
}
}
//判断游戏是否结束
bool IsGameOver()
{
bool topLineHaveRock = false;//顶行是否有方块
bool bottomLineHaveRock = false;
for (int i = 1; i < xROCK_SQUARE_NUM; ++i)
{
if (game_board[1][i] == 1)
topLineHaveRock = true;
if (game_board[yROCK_SQUARE_NUM][i] == 1)
bottomLineHaveRock = true;
}
if (bottomLineHaveRock && topLineHaveRock)
return true;
else
return false;
}
main.cpp
#include"Head.h"
#include"Draw.h"
#include"Init.h"
#include"game.h"
int main()
{
initgraph(WINDOW_WIDTH,WINDOW_HIGH);
DrawGameWindow();
//使用 API 函数修改窗口名称
HWND hWnd = GetHWnd();
SetWindowText(hWnd, _T("俄罗斯方块"));
InitGame();
PlayGame();
getchar();
closegraph();
system("pause");
return 0;
}
配置文件:RockShape.ini
@###
@###
@@##
####
@@@#
@###
####
####
@@##
#@##
#@##
####
##@#
@@@#
####
####
****
#@##
#@##
@@##
####
@###
@@@#
####
####
@@##
@###
@###
####
@@@#
##@#
####
####
****
#@##
@@@#
####
####
@###
@@##
@###
####
@@@#
#@##
####
####
#@##
@@##
#@##
####
****
#@##
@@##
@###
####
@@##
#@@#
####
####
****
@###
@@##
#@##
####
#@@#
@@##
####
####
****
@###
@###
@###
@###
@@@@
####
####
####
****
@@##
@@##
####
####
****
来源:https://blog.csdn.net/wenqiang1208/article/details/71245082
0
投稿
猜你喜欢
- 活锁与死锁活锁活锁同样会发生在多个相互协作的线程间,当他们为了彼此间的响应而相互礼让,使得没有一个线程能够继续前进,那么就发生了活锁。同死锁
- 新建Rest服务接口:[ServiceContract]public interface IService1{ &nb
- 继承ClassLoader并且重写findClass方法就可以自定义一个类加载器,具体什么是类加载器以及类加载器的加载过程与顺序下次再说,下
- sqlite是啥?1、一种轻型数据库2、关系型数据库3、占用资源很低,几百K内存,适合嵌入式设备4、支持windows、linux、unix
- RecyclerView 是 android-support-v7-21 版本中新增的一个 Widgets, 还有一个 CardView 会
- 自定义控件在android中无处不见,自定义控件给了我们很大的方便。比如说,一个视图为imageview ,imagebutton ,tex
- 背景接上文《失踪人口回归,mybatis-plus 3.3.2 发布》[1] ,提供了一个非常实用的功能 「数据安全保护」 功能,不仅支持数
- 1.1 解决方案名和项目名上右键——重命名如下图:改完后效果如下:1.2 接下来要改名 代码中的名称
- 前言泛型在java中有很重要的地位,无论是开源框架还是JDK源码都能看到它。毫不夸张的说,泛型是通用设计上必不可少的元素,所以真正理解与正确
- 什么是ApplicationContext?它是Spring的核心,Context我们通常解释为上下文环境,但是理解成容器会更好些。 App
- 在Android开发中,我们不光可以使用已有的实现方式,而且,我们还可以利用Android这个智能手机平台,实现一些比较有特色的功能。本篇文
- 1. private void Form1_Load(object &
- Java 8 最大的特性无异于更多地面向函数,比如引入了lambda等,可以更好地进行函数式编程。前段时间无意间发现了map.merge()
- 本文实例讲述了Android编程基于重力传感器实现横竖屏放向切换功能。分享给大家供大家参考,具体如下:最近项目中用到了vr视频播放,因为自己
- 问题我们发现,之所以我们现在离不开 xml 配置文件,是因为我们有一句很关键的配置:<!-- 告知spring框架在,读取配置文件,创
- 先贴代码,后面做一些简单说明:public static string sendPostHttpRequest_2(string url,
- 1.概述在本快速教程中,我们将学习如何设置Spring Security LDAP。在我们开始之前,了解一下LDAP是什么? - 它代表轻量
- Spring Boot如何实现分布式锁的自动释放在分布式系统中,为了保证数据的一致性和可靠性,常常需要使用分布式锁。在实际开发中,我们可以使
- 最近这段时间一直在看Android,利用Listview去实现点赞功能,下面给大家介绍下基本思路。基本思路:进入界面–》获取数据–》 在Li
- 本文实例讲述了Java Web实现添加定时任务的方法。分享给大家供大家参考,具体如下:定时任务时间控制类/** * 定时任务时间控制 * *