📄 snake.cpp
字号:
//
// Online Game Cheats Client.dll hook
// Copyright (c) system 2001-2002
// Copyright (c) bunny771 2001-2002
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// NOTE:
// GNU license doesn't cover Engine directory.
// Content of Engine directory is copyrighted (c) 1999, 2000, by Valve LLC
// and it is licensed under Valve's proprietary license (see original HL SDK).
//
#include <windows.h>
#include "engine/wrect.h"
#include "engine/cl_dll.h"
#include <vector>
#include <string>
using namespace std;
#include "cvar.h"
#include "client.h"
#include "timehandling.h"
#include "stringfinder.h"
#include "color.h"
#include "snake.h"
Snake snake;
enum{ SNAKE_BOX=10 };
enum{ SNAKE_WIDTH = SNAKE_FIELDS_X*SNAKE_BOX, SNAKE_HEIGHT = SNAKE_FIELDS_Y*SNAKE_BOX };
#define REPEAT_NTIMES(n,action) {for(int i=0;i<n;i++){action} }
//========================================================================================
void Snake::reset()
{
dead = false;
run_starttime = ClientTime::current;
head = 0;
score = 0;
wait_time = 0.2;
dir = next_dir = 2;
for(int x=0;x<SNAKE_FIELDS_X;x++)
for(int y=0;y<SNAKE_FIELDS_Y;y++)
{
playfield[x][y] = CONTENT_EMPTY;
}
for(int x=0;x<SNAKE_FIELDS_X;x++)playfield[x][0] = playfield[x][SNAKE_FIELDS_Y-1] = CONTENT_WALL;
for(int y=0;y<SNAKE_FIELDS_Y;y++)playfield[0][y] = playfield[SNAKE_FIELDS_X-1][y] = CONTENT_WALL;
switch(level)
{
case 1:
{
int x1 = SNAKE_FIELDS_X/3;
int x2 = 2*SNAKE_FIELDS_X/3;
int y1 = SNAKE_FIELDS_Y/5;
int y2 = 4*SNAKE_FIELDS_Y/5;
for(int y=y1;y<y2;y++) { playfield[x1][y]=CONTENT_WALL;playfield[x2][y]=CONTENT_WALL; }
break;
}
case 2:
{
int x1 = SNAKE_FIELDS_X/2;
for(int y=0;y<SNAKE_FIELDS_Y;y++) if(y&1) playfield[x1][y]=CONTENT_WALL;
break;
}
case 3:
{
int x1 = SNAKE_FIELDS_X/3;
int x2 = 2*SNAKE_FIELDS_X/3;
for(int y=0;y<SNAKE_FIELDS_Y;y++) { if(y&1) playfield[x1][y]=CONTENT_WALL; else playfield[x2][y]=CONTENT_WALL; }
break;
}
case 4:
{
int x1 = SNAKE_FIELDS_X/6;
int x2 = 5*SNAKE_FIELDS_X/6;
int y1 = SNAKE_FIELDS_Y/5;
int y2 = 4*SNAKE_FIELDS_Y/5;
bool flipflop = true;
for(int x=x1;x<=x2;x+=x1)
{
if(flipflop) for(int y=0;y<y2;y++) playfield[x][y]=CONTENT_WALL;
else for(int y=y1;y<SNAKE_FIELDS_Y;y++) playfield[x][y]=CONTENT_WALL;
flipflop=!flipflop;
}
break;
}
}
body.clear();
REPEAT_NTIMES(10, {addBody(8,10);} );
placeNewItem();
}
//========================================================================================
Snake::Snake(){ level=0; reset(); }
//========================================================================================
void Snake::nextLevel()
{
level++;
if(level>4) level=0;
reset();
}
//========================================================================================
void Snake::addBody(int x,int y)
{
playfield[x][y] = CONTENT_SNAKE;
body.push_back( (x<<16) + y );
}
//========================================================================================
inline void tintBackground(int x,int y,int w,int h,ColorEntry* clr)
{
gEngfuncs.pfnFillRGBA(x,y,w,h,clr->r,clr->g,clr->b,clr->a);
}
//========================================================================================
void Snake::command(const string& arg)
{
if(!dead)
{
if(arg=="left" ) { if( visible ) setRunning(true ); if(dir!=2) next_dir=1; }
else if(arg=="right") { if( visible ) setRunning(true ); if(dir!=1) next_dir=2; }
else if(arg=="up" ) { if( visible ) setRunning(true ); if(dir!=4) next_dir=3; }
else if(arg=="down" ) { if( visible ) setRunning(true ); if(dir!=3) next_dir=4; }
}
if(arg=="hide" ) { visible=false;setRunning(false); }
else if(arg=="show" ) { visible=true ;setRunning(false); }
else if(arg=="reset") { visible=true ;setRunning(false); reset(); }
else if(arg=="level") { visible=true ;setRunning(false); nextLevel(); reset(); }
}
//========================================================================================
void Snake::setRunning(bool running_new)
{
running = running_new;
}
//========================================================================================
void Snake::grow()
{
// get tail
int tail = head+1; if(tail==body.size()) tail=0;
body.push_back(0);
for(int i = body.size()-1;i>tail; --i) { body[i]=body[i-1]; }
}
//========================================================================================
void Snake::placeNewItem()
{
int x,y;
do{
x = rand()%SNAKE_FIELDS_X;
y = rand()%SNAKE_FIELDS_Y;
} while(playfield[x][y]!=CONTENT_EMPTY);
playfield[x][y]=CONTENT_ITEM;
}
//========================================================================================
void Snake::frame()
{
// draw
if(visible)
{
int screenx = cvar.snake_x;
int screeny = cvar.snake_y;
extern bool oglSubtractive;
oglSubtractive = true;
for(int x=0;x<SNAKE_FIELDS_X;x++,screenx+=SNAKE_BOX,screeny = cvar.snake_y)
for(int y=0;y<SNAKE_FIELDS_Y;y++,screeny+=SNAKE_BOX)
{
ColorEntry* clr=colorList.get(25);
switch(playfield[x][y])
{
case CONTENT_EMPTY: clr=colorList.get(25);break;
case CONTENT_SNAKE: clr=colorList.get(26);break;
case CONTENT_ITEM: clr=colorList.get(27);break;
case CONTENT_WALL: clr=colorList.get(28);break;
}
tintBackground(screenx,screeny,SNAKE_BOX,SNAKE_BOX,clr);
}
oglSubtractive = false;
void DrawHudStringCenter (int x, int y, int r, int g, int b, const char *fmt, ... );
int mid_x = cvar.snake_x+(SNAKE_WIDTH /2);
int mid_y = cvar.snake_y+(SNAKE_HEIGHT/2);
if(dead) DrawHudStringCenter(mid_x,mid_y,200,100,10,"Score: %d",score);
else if(!running)
{
DrawHudStringCenter(mid_x,mid_y-16,222,222,0,"PAUSED");
DrawHudStringCenter(mid_x,mid_y ,222,222,0,"Level: %d",level);
DrawHudStringCenter(mid_x,mid_y+16,222,222,0,"Score: %d",score);
DrawHudStringCenter(mid_x,mid_y+32,222,222,0,"High Score: %d",cvar.snake_highscore[level]);
}
}
if(running)
{
// move run_starttime clientTime::current
register double passedTime = (ClientTime::current-run_starttime);
if(passedTime>wait_time)
{
run_starttime = ClientTime::current;
// old head coords
DWORD head_x = body[head]>>16;
DWORD head_y = body[head]&0xFFFF;
// advance, get tail pos, clear tail
head++; if(head==body.size()) head=0;
DWORD tail_x = body[head]>>16;
DWORD tail_y = body[head]&0xFFFF;
playfield[tail_x][tail_y] = CONTENT_EMPTY;
// new head pos
switch(next_dir)
{
case 1: head_x--; break; // left
case 2: head_x++; break; // right
case 3: head_y--; break; // up
case 4: head_y++; break; // down
}
dir = next_dir;
body[head] = (head_x<<16)+head_y;
switch(playfield[head_x][head_y])
{
case CONTENT_WALL:
gEngfuncs.pfnPlaySoundByName("debris/bustmetal2.wav", 1.0);
if(score>cvar.snake_highscore[level]) cvar.snake_highscore[level]= score;
dead = true;
running = false;
return;
case CONTENT_SNAKE:
gEngfuncs.pfnPlaySoundByName("common/bodydrop4.wav", 1.0);
if(score>cvar.snake_highscore[level]) cvar.snake_highscore[level]= score;
dead = true;
running = false;
return;
case CONTENT_ITEM:
gEngfuncs.pfnPlaySoundByName("buttons/bell1.wav", 1.0);
grow();
placeNewItem();
if(wait_time>0.03) wait_time -= 0.002;
score += (int)(1.0/wait_time);
break;
}
// update Snake fields
for(unsigned int i=0;i<body.size();i++)
{
DWORD coord = body[i];
playfield[coord>>16][coord&0xFFFF] = CONTENT_SNAKE;
}
}// frameocunter
} else { // !running
run_starttime = ClientTime::current;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -