Snake, snejk, wąż - wszyscy chyba znają tą grę. Bardzo prosty kod, gra napisana na standardowej formie. Obsługa za pomocą klawiatury, proste zliczanie punktów, wąż się powiększa z każdym zjedzonym kawałkiem.
Teoretycznie nie ma końca gry, za wyjątkiem kolizji. Wszystko zależy od prędkości ustawianej w kodzie.
Przekompilowałem ostatnio pod VS2010, więc nie powinno być raczej problemu z odpaleniem
Dostępny cały kod źródłowy z kodem projektu - pobierz w dysku google.
Poniżej kawałek kodu:
snejk.h
#pragma onceform1.h
ref class snejk //klasa modułu węża
{
public:
System::Drawing::Pen ^kolor; //zawiera pen który przechowuje kolor
System::Drawing::Rectangle ^modul; //zawiera prostokąt (jak i jego współrzędne)
snejk(System::Drawing::Color color,int x,int y) //konstruktor, podajemy kolor i współrzędne
{
this->modul = gcnew System::Drawing::Rectangle(x,y,10,10);
this->kolor = gcnew System::Drawing::Pen(color,3);
}
virtual ~snejk(void) //destruktor
{
}
void przesun_na_pozycje(snejk^ modul_tmp) //przesuwa na pozycję podanego obiektu tej samej klasy
{
this->modul->X = modul_tmp->modul->X;
this->modul->Y = modul_tmp->modul->Y;
}
void przesun_na_pozycje(int x, int y) //przesuwa na pozycję podanych współrzędnych
{
this->modul->X = x;
this->modul->Y = y;
}
void rysuj(System::Drawing::Graphics^ grafa) //rysuje prostokąt
{
grafa->DrawRectangle(this->kolor,*this->modul);
}
bool sprawdz_kolizje_z_punktem(int x, int y) //sprawdza kolizję z punktem
{
if((this->modul->X == x )&&(this->modul->Y == y)) //jezeli punkty mają te same pozycje
return true;
else //jeśli nie ma kolizji
return false;
}
};
#pragma once
#include "snejk.h"
namespace projekt_s {
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
/// <summary>
/// Summary for Form1
///
/// WARNING: If you change the name of this class, you will need to change the
/// 'Resource File Name' property for the managed resource compiler tool
/// associated with all .resx files this class depends on. Otherwise,
/// the designers will not be able to interact properly with localized
/// resources associated with this form.
/// </summary>
public ref class Form1 : public System::Windows::Forms::Form
{
public:
System::Drawing::Pen^ pen; //pen do rysowania weza oraz jabłek
System::Collections::Generic::List<snejk^>^ waz;//lista zawierająca elementy klasy snejk - reprezentuje weza
int jablko_x, jablko_y, xx, yy, kierunek, punkty; //xx, yy to obecna pozycja kursora
bool gra; //zmienna pomocnicza ustalajaca czy gra jest w trakcie czy nie
private: System::Windows::Forms::Label^ label1;
private: System::Windows::Forms::Label^ label2;
private: System::Windows::Forms::Label^ label3;
private: System::Windows::Forms::Timer^ timer1;
public:
Form1(void)
{
InitializeComponent();
//
//TODO: Add the constructor code here
//
this->gra = false;
this->pen = gcnew System::Drawing::Pen(Color::Red,3); //pen do jabłek
this->timer1->Interval = 250; //czas na 25ms
//this->nowa_gra(); //nowa gra //rysuje się waz niepotrzebnie na początku, a pozniej zmienia pozycję jabłko po enterze bo jescze raz jest jest losowana pozycja
}
protected:
/// <summary>
/// Clean up any resources being used.
/// </summary>
~Form1()
{
if (components)
{
delete components;
}
}
private: System::ComponentModel::IContainer^ components;
protected:
protected:
private:
/// <summary>
/// Required designer variable.
/// </summary>
#pragma region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
void InitializeComponent(void)
{
this->components = (gcnew System::ComponentModel::Container());
this->timer1 = (gcnew System::Windows::Forms::Timer(this->components));
this->label1 = (gcnew System::Windows::Forms::Label());
this->label2 = (gcnew System::Windows::Forms::Label());
this->label3 = (gcnew System::Windows::Forms::Label());
this->SuspendLayout();
//
// timer1
//
this->timer1->Tick += gcnew System::EventHandler(this, &Form1::timer1_Tick);
//
// label1
//
this->label1->AutoSize = true;
this->label1->Location = System::Drawing::Point(-1, 483);
this->label1->Name = L"label1";
this->label1->Size = System::Drawing::Size(43, 13);
this->label1->TabIndex = 0;
this->label1->Text = L"Punkty:";
//
// label2
//
this->label2->AutoSize = true;
this->label2->Location = System::Drawing::Point(48, 483);
this->label2->Name = L"label2";
this->label2->Size = System::Drawing::Size(13, 13);
this->label2->TabIndex = 1;
this->label2->Text = L"0";
//
// label3
//
this->label3->AutoSize = true;
this->label3->ForeColor = System::Drawing::Color::Red;
this->label3->Location = System::Drawing::Point(7, 30);
this->label3->Name = L"label3";
this->label3->Size = System::Drawing::Size(202, 13);
this->label3->TabIndex = 2;
this->label3->Text = L"Aby rozpocząć nową grę naciśnij ENTER";
//
// Form1
//
this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
this->ClientSize = System::Drawing::Size(484, 497);
this->Controls->Add(this->label3);
this->Controls->Add(this->label2);
this->Controls->Add(this->label1);
this->MaximizeBox = false;
this->MaximumSize = System::Drawing::Size(500, 535);
this->MinimumSize = System::Drawing::Size(500, 535);
this->Name = L"Form1";
this->Text = L"Snejk";
this->Paint += gcnew System::Windows::Forms::PaintEventHandler(this, &Form1::Form1_Paint);
this->KeyDown += gcnew System::Windows::Forms::KeyEventHandler(this, &Form1::Form1_KeyDown);
this->ResumeLayout(false);
this->PerformLayout();
}
#pragma endregion
public: void losuj_jablko(){ //losuje pozycje połozenia jabłka
Random^ randObj = gcnew Random;
this->jablko_x=(randObj->Next(1,48)*10); //połozenie x,y jabłka musi znajdować się w obszarze gry
this->jablko_y=(randObj->Next(1,48)*10);
}
public: void losuj_start() //losujemy kierunek w którym będzie się poruszał waz po starcie
{
Random^ rand = gcnew Random;
int los;
los = rand->Next(1,4); //losujemy liczbę od 1 do 3
if(los==3) //3 jest zabronione bo 3 oznacza kierunek w lewo (wąż ma głowę z prawej strony i jest rysowany z prawej do lewej)
this->kierunek = 4; //zeby nie było 3 kierunku to przypisuje 4 i problem z głowy
else
this->kierunek = los; //jezeli to 1 lub 2 (góra/dół)
}
private: System::Void Form1_KeyDown(System::Object^ sender, System::Windows::Forms::KeyEventArgs^ e) {
switch(e->KeyCode)
{
case Keys::Up:
if(kierunek!=2) //zapobiega obróceniu węża w górę jeśli porusza się w dół
kierunek = 1;
break;
case Keys::Down:
if(kierunek!=1) //jw tylko na odwrót
kierunek = 2;
break;
case Keys::Left:
if(kierunek!=4) //zapobiega odwróceniu węża w lewo jeśli jest zwrócony w prawo
kierunek = 3;
break;
case Keys::Right:
if(kierunek!=3) //jw tylko na odwrót
kierunek = 4;
break;
case Keys::Enter:
if(!this->gra) //jezeli false, jeżeli gra stoi
{
this->label3->Visible = false; //wyłączy widocznosc tekstu
this->timer1->Enabled = true; //załączy timer
this->gra = true; //aktywuje gre
this->nowa_gra();
}
break;
}
}
private: System::Void timer1_Tick(System::Object^ sender, System::EventArgs^ e) {
this->Refresh(); //odświeżam widok formy
if (kierunek == 1) //jezeli w górę
{
this->xx=this->xx;
this->yy=this->yy-10;
}
if (kierunek == 2)//jezeli w dół
{
this->xx=this->xx;
this->yy=this->yy+10;
}
if (kierunek == 3) //jeżeli w lewo
{
this->xx=this->xx-10;
this->yy=this->yy;
}
if (kierunek == 4)//jezeli w prawo
{
this->xx=this->xx+10;
this->yy=this->yy;
}
if((this->sprawdz_kolizje_z_wezem(this->xx,this->yy))||this->sprawdz_kolizje_ze_sciana())
{ //jezeli nastapiła kolizja z jedna ze scian lub z samym sobą to koniec gry
this->gra = false; //dezaktywuje gre
return this->game_over();
}
else
{ //w przeciwnym wypadku sprawdzamy kolizje z jabłkiem
if (this->waz[0]->sprawdz_kolizje_z_punktem(this->jablko_x,this->jablko_y))//jezeli pierwszy element wejdzie na pozycje jabłka
{
snejk ^temp;
this->losuj_jablko(); //losuje nowa pozycje jabłka
temp = gcnew snejk(System::Drawing::Color::Red,0, 0); //tworzy nowy obiekt klasy snejk (dowolne współrzedne, pozniej dostanie współrzedne po ostatnim elemencie)
this->waz->Add(temp); //dodaje element do listy
this->punkty+=10; //zwiekszamy punkty
this->label2->Text = this->punkty.ToString(); //wyswietlamy punkty
}
//a następnie przesuwamy punkty od elementów
snejk ^tmp, ^tmp1;
tmp1 = gcnew snejk(System::Drawing::Color::Red,10,10); //nowy obiekt pomocniczy
tmp = gcnew snejk(System::Drawing::Color::Red,10,10); //nowy obiekt pomocniczy
for(int i=0;i<=this->waz->Count-1;i++) //przeglada kazdy modul w liscie
{
if(i==0)//dla pierwszego elementu
{
tmp->przesun_na_pozycje(this->waz[i]); //przekazuje obecne wspólrzedne modułu do pomocniczej
this->waz[i]->przesun_na_pozycje(this->xx,this->yy); //obecny moduł (pierwszy) przesuwa na pozycje xx, yy
}
else //dla pozostałych elementów
{
tmp1->przesun_na_pozycje(this->waz[i]); //zapisuje obecną pozycje do drugiej pomocniczej
this->waz[i]->przesun_na_pozycje(tmp); //obecny element przestawia na pozycje poprzedniego elementu
tmp->przesun_na_pozycje(tmp1); //do pomocniczej zapisuje poprzednia pozycję (przed przedstawieniem) do pomocniczej
}
}
tmp1->~snejk(); //destruktory pomocniczych obiektów;
tmp->~snejk();
}
}
private: System::Void Form1_Paint(System::Object^ sender, System::Windows::Forms::PaintEventArgs^ e) {
if(this->gra) //jezeli gra jest aktywna to zezwala na rysowanie
{
e->Graphics->DrawRectangle(this->pen, this->jablko_x, this->jablko_y, 10, 10); //rysuje jablko na pozycji
for each(snejk ^modul1 in this->waz) //dla kazdego modulu weza
modul1->rysuj(e->Graphics); //rysuje ten element
}
}
bool sprawdz_kolizje_z_wezem(int x, int y) //sprawdza czy współrzedne punktu nie są równe współrzednym każdego modułu
{
for each(snejk ^tmp in this->waz) //dla kazdego elementu
{
if(tmp->sprawdz_kolizje_z_punktem(x,y)) //sprawdza kolizje pojedynczego modułu
return true;
}
return false;
}
bool sprawdz_kolizje_ze_sciana() // sprawdza czy obecny punkt nie wchodzi na scianę
{
if((this->xx==-10)&&(this->yy<=490)) //sciana lewa
return true;
else if((this->xx<=490) && (this->yy==-10))// sciana górna
return true;
else if((this->xx==490) && (this->yy<=490))//sciana prawa
return true;
else if((this->xx<=490) && (this->yy==490))//sciana dolna
return true;
else
return false; //jezeli brak kolizji ze ścianą
}
void nowa_gra() //nowa gra
{
this->pen->Color = System::Drawing::Color::Red; //kolor czerwony
this->waz = gcnew System::Collections::Generic::List<snejk^>();
this->punkty = 0; //reset punktów
this->label2->Text = "0"; //wyswietlanie punktów tez
snejk ^modul; //tworzymy sobie 4 elementowego weza
modul = gcnew snejk(System::Drawing::Color::Green,250,250); //o zielonej głowie, obróconego w prawo
this->waz->Add(modul); //wszystko dodajemy do listy po kolei
modul = gcnew snejk(System::Drawing::Color::Red,240,250);//kolejne moduły już czerwone
this->waz->Add(modul); //itd
modul = gcnew snejk(System::Drawing::Color::Red,230,250);
this->waz->Add(modul);
modul = gcnew snejk(System::Drawing::Color::Red,220,250);
this->waz->Add(modul);
this->losuj_jablko();//losujemy pozycje jabłka (mozna dodać funcję zeby nie wrzuciło jabłka na węża)
this->losuj_start(); //losujemy pozycje kierunku w którym pojdzie wąż po włączeniu timera (3 jest zabroniony)
this->xx = 250; //wpółrzedne poruszania się takie jak pozycja głowy
this->yy = 250;
this->pen->Color = System::Drawing::Color::GreenYellow; //zmieniamy kolor - bo później już same jabłka się będą rysowały
}
void game_over() //koniec gry
{
this->label3->Visible = true; //włączy widocznośc tekstu
this->timer1->Enabled=false; //zatrzymujemy timer
this->label3->Text = "GAME OVER \nTwoje punkty: "+this->punkty.ToString()+"\nAby rozpoczac grę naciśnij ENTER"; //statystyki + info
for each(snejk ^tmp in this->waz) //czyscimy liste węża
tmp->~snejk();
this->waz->Clear();
}
};
}

Brak komentarzy:
Prześlij komentarz