Creating the Snake Game using a class
2 次查看(过去 30 天)
显示 更早的评论
I'm having trouble making the Snake game using a class def, my code just continously loops & keeps recreating the graph. I'm stuck & don't know what I need to do to be able to stop the the graph from constantly remaking itself & make the snake move.
classdef snake < handle
properties
gameinput = 'k';
player1 = [];
board = [];
lose = [];
character = 1;
ex = 0;
end
methods
%constructor
function self = snake(varargin)
if ~isempty(varargin)
self.gameinput = varargin{1}
if nargin > 1
self.player1 = varargin{2};
end
end
end
%controls game flow
function play(self)
if isempty(self.lose)
draw_board(self)
end
end
%creates game board
function draw_board(self)
axis_limit = 16;
d = 0;
ate = 0;
x = round(axis_limit/2); %starting point
y = round(axis_limit/2); %starting point
a =randi([1 axis_limit-1],1);%generates random x coordinate for food
b =randi([1 axis_limit-1],1);%generates random y coordinate for food
d =randi([1,4]);% generates random direction to start in for snake
snake(1,1:2)=[x y];%defines the snake for x and y coordinates
size_snake=size(snake);
size_snake=size_snake(1);
food = [a b]; %defines coords for the food
test
while (self.ex~=1)%runs the snake as long as q is not pressed
size_snake=size(snake);
size_snake=size_snake(1);
for l=size_snake+ate:-1:2
snake(l,:)=snake(l-1,:);
end
switch d %calling callback function
case 1
snake(1,2)=snake(1,2)+1;%add value of 1 to y position
case 2
snake(1,2)=snake(1,2)-1;%subtract value of 1 to y position
case 3
snake(1,1)=snake(1,1)+1;%add value of 1 to x position
case 4
snake(1,1)=snake(1,1)-1;%subtracts value of 1 to x position
end
draw_snake(self)
if snake(1,1)==food(1) && snake(1,2)==food(2)%if the snake and food are in the same position
ate=1;
food(1) = randi([1 axis_limit-1]);%creates a new x position for the food
food(2) = randi([1 axis_limit-1]);%creates a new y position for the food
else
ate=0;
end
snake=snake-((snake>axis_limit).*(axis_limit+1));
snake=snake+((snake<0).*(axis_limit+1));
end
end
function draw_snake(self)
axis_limit = 8;
d = 0;
ate = 0;
x = round(axis_limit/2); %starting point
y = round(axis_limit/2); %starting point
a =randi([1 axis_limit-1],1);%generates random x coordinate for food
b =randi([1 axis_limit-1],1);%generates random y coordinate for food
d =randi([1,4]);% generates random direction to start in for snake
snake(1,1:2)=[x y];%defines the snake for x and y coordinates
food = [a b]; %defines coords for the food
size_snake=size(snake);
size_snake=size_snake(1);
for p = 1:size_snake
plot(snake(p,1),snake(p,2), 'wo')
hold on
end
plot(food(1,1),food(1,2), 'rs')%creates the vectors for the food and snake and plots them
drawnow
whitebg([0 0 0])%creates black background
axis([0, axis_limit, 0, axis_limit])%creates the axis for gameplay
hold off
end
%controls the movement of the snake
function move_snake(self)
switch self.character
case 'q'
self.ex=1;
case 30 % arrow direction
if(d~=2)
d = 1; %up d=1
end
case 31
if(d~=1)
d = 2; %down d=2
end
case 29
if(d~=4)
d = 3; %right d=3
end
case 28
if(d~=3)
d = 4; %left d=4
end
end
end
end
end
2 个评论
TADA
2018-12-12
You're testing for changes in self.character, but you're not changing it anywhere. unless there's some more code you didn't post, you should be listening to some keyboard press event
check out some of the answers to these questions should help you out:
回答(1 个)
TADA
2018-12-13
To understand whats happening, lets build a small class with a function or two:
classdef run
methods
function start(this)
disp('start running');
end
function stop(this)
disp('stop running');
end
end
end
Ok, now when you declare an object of this type you can start or stop it:
rn = run();
start(rn); % or like that: rn.start();
start running
stop(rn); % or like that: rn.stop();
stop running
but, if you try to invoke these methods with an argument of a different type you get an exception:
start(10);
Undefined function 'start' for input arguments of type 'double'.
stop(figure());
Undefined function 'start' for input arguments of type 'matlab.ui.Figure'.
thats because this methods is only defined for objects of type run, unlike regular functions you declare in an .m file, where you can send any type of input as long as the function knows how to handle the input.
This issue can be resolved using static methods:
classdef run
methods
function start(this)
disp('start running');
end
function stop(this)
disp('stop running');
end
end
methods(Static)
function start2(obj, ~)
% notice the second parameter: ~, we'll come back to that later
disp([class(obj) ' starting to run']);
end
end
end
run.start2(rn);
run starting to run
run.start2(10);
double starting to run
run.start2(fig)
matlab.ui.Figure starting to run
If you look here, you can see that in most cases Matlab events expect function handles with this signature:
function callbackFunction(src,event)
where src is the source of the event (in your case probably the figure) and event is an object which contains extra parameters about the event (such as which key was pressed, etc.). ok, so that's the reason you got the error in the first place. so now you can register the a sunction handle to a static method instead of a non-static method, something like that:
figure('KeyPressFcn',@run.start2);
That event argument is the reason I declared another parameter in that start2 method, because the event listener will send two arguments, and if you don'tt declare it you will have an exception for sending too many input arguments. Ok, so that solves the exception, but not your problem, since you now lose the reference to your self object (because this is a static method). To overcome this we can use closures instead (add this method to the run class):
function capture(self)
figure('KeyPressFcn',@(src, event) start(self));
end
now the event handler will invoke the start method with the self variable declared in the containing method.
The beautiful thing about closures, is they maintain the workspace of their declaring function.
Bottom line:
function theFunctionWhereYouRegisterToTheEvent(self)
figure('KeyPressFcn',@(src, event) move_snake(self, event));
end
you'd probably want to send that event argument to your move_snake method as well
0 个评论
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!