You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

428 lines
12 KiB

<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle 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 3 of the License, or
// (at your option) any later version.
//
// Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This file creates a board for "Snakes and Ladders".
*
* @package mod_game
* @copyright 2007 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Create snakes board
*
* @param string $imageasstring
* @param int $colsx
* @param int $colsy
* @param int $ofstop
* @param int $ofsbottom
* @param int $ofsright
* @param int $ofsleft
* @param stdClass $board
* @param int $setwidth
* @param int $setheight
*/
function game_createsnakesboard($imageasstring, $colsx, $colsy, $ofstop, $ofsbottom,
$ofsright, $ofsleft, $board, $setwidth, $setheight) {
global $CFG;
$dir = $CFG->dirroot.'/mod/game/snakes/1';
$im = imagecreatefromstring($imageasstring);
// Check if need resize.
if ( $setwidth > 0 or $setheight > 0) {
$source = $im;
$width = imagesx($source);
$height = imagesy($source);
$factorx = $setwidth / $width;
$factory = $setheight / $height;
$factor = ($factorx < $factory || $factory == 0 ? $factorx : $factory);
$newwidth = $width * $factor;
$newheight = $height * $factor;
$im = imagecreatetruecolor($newwidth, $newheight);
imagecopyresized($im, $source, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
}
$cx = imagesx($im) - $ofsright - $ofsleft;
$cy = imagesy($im) - $ofstop - $ofsbottom;
$color = 0xFF0000;
for ($i = 0; $i <= $colsx; $i++) {
imageline( $im, $ofsleft + $i * $cx / $colsx, $ofstop, $ofsleft + $i * $cx / $colsx, $cy + $ofstop, $color);
}
for ($i = 0; $i <= $colsy; $i++) {
imageline( $im, $ofsleft, $ofstop + $i * $cy / $colsy, $cx + $ofsleft, $ofstop + $i * $cy / $colsy, $color);
}
$filenamenumbers = $dir.'/numbers.png';
$imgnumbers = imagecreatefrompng( $filenamenumbers);
$sizenumbers = getimagesize ($filenamenumbers);
for ($iy = 0; $iy < $colsy; $iy++) {
if ($iy % 2 == 0) {
$inc = false;
$num = ($colsy - $iy) * $colsy;
} else {
$inc = true;
$num = ($colsy - $iy) * $colsy - ($colsy - 1);
}
$ypos = $iy * $cy / $colsy + $ofstop;
for ($ix = 0; $ix < $colsx; $ix++) {
$xpos = $ix * $cx / $colsx + $ofsleft;
shownumber( $im, $imgnumbers, $num, $xpos, $ypos, $cx / 4, $cy / 4, $sizenumbers);
$num = ($inc ? $num + 1 : $num - 1);
}
}
makeboard( $im, $dir, $cx, $cy, $board, $colsx, $colsy, $ofsleft, $ofstop);
return $im;
}
/**
* Compute coordinates
*
* @param int $pos
* @param int $x
* @param int $y
* @param int $colsx
* @param int $colsy
*/
function computexy( $pos, &$x, &$y, $colsx, $colsy) {
$x = ($pos - 1) % $colsx;
$y = ($colsy - 1) - floor( ($pos - 1) / $colsy);
if ($y % 2 == 0) {
$x = ($colsx - 1) - $x;
}
}
/**
* Make board
*
* @param object $im
* @param int $dir
* @param int $cx
* @param int $cy
* @param object $board
* @param int $colsx
* @param int $colsy
* @param int $ofsleft
* @param int $ofstop
*/
function makeboard( $im, $dir, $cx, $cy, $board, $colsx, $colsy, $ofsleft, $ofstop) {
$a = explode( ',', $board);
foreach ($a as $s) {
if (substr( $s, 0, 1) == 'L') {
makeboardL( $im, $dir, $cx, $cy, substr( $s, 1), $colsx, $colsy, $ofsleft, $ofstop);
} else {
makeboardS( $im, $dir, $cx, $cy, substr( $s, 1), $colsx, $colsy, $ofsleft, $ofstop);
}
}
}
/**
* Make board ladders
*
* @param object $im
* @param string $dir
* @param int $cx
* @param int $cy
* @param string $s
* @param int $colsx
* @param int $colsy
* @param int $ofsleft
* @param int $ofstop
*/
function makeboardl( $im, $dir, $cx, $cy, $s, $colsx, $colsy, $ofsleft, $ofstop) {
$pos = strpos( $s, '-');
$from = substr( $s, 0, $pos);
$to = substr( $s, $pos + 1);
computexy( $from, $startx, $starty, $colsx, $colsy);
computexy( $to, $x2, $y2, $colsx, $colsy);
if (($x2 < $startx) and ($y2 < $starty)) {
$temp = $x2; $x2 = $startx; $startx = $temp;
$temp = $y2; $y2 = $starty; $starty = $temp;
}
$movex = $x2 - $startx;
$movey = $y2 - $starty;
$letter = ( $movex * $movey < 0 ? 'b' : 'a');
$oldstartx = $startx; $oldmovex = $movex; $oldstarty = $starty; $oldmovey = $movey;
if ($movex < 0) {
$startx += $movex;
$movex = -$movex;
}
if ($movey < 0) {
$starty += $movey;
$movey = -$movey;
}
$stamp = 0;
if ($letter == 'b') {
$file = $dir.'/l'.$letter.$movey.$movex.'.png';
if (file_exists( $file)) {
$stamp = game_imagecreatefrompng( $file);
} else {
$file = $dir.'/la'.$movey.$movex.'.png';
$source = game_imagecreatefrompng( $file);
if ( $source != 0) {
$stamp = imagerotate($source, 90, 0);
}
}
} else {
$file = $dir.'/la'.$movex.$movey.'.png';
$stamp = game_imagecreatefrompng( $file);
}
$dstx = $startx * $cx / $colsx;
$dsty = $starty * $cy / $colsy;
$dstw = ($movex + 1) * $cx / $colsx;
$dsth = ($movey + 1) * $cy / $colsy;
if ($stamp == 0) {
game_printladder( $im, $file, $dstx + $ofsleft, $dsty + $ofstop, $dstw, $dsth, $cx / $colsx, $cy / $colsy);
} else {
imagecopyresampled( $im, $stamp, $ofsleft + $dstx, $ofstop + $dsty, 0, 0, $dstw, $dsth,
100 * $movex + 100, 100 * $movey + 100);
}
}
/**
* Make board snakes
*
* @param object $im
* @param string $dir
* @param int $cx
* @param int $cy
* @param string $s
* @param int $colsx
* @param int $colsy
* @param int $ofsleft
* @param int $ofstop
*/
function makeboards( $im, $dir, $cx, $cy, $s, $colsx, $colsy, $ofsleft, $ofstop) {
$pos = strpos( $s, '-');
$from = substr( $s, 0, $pos);
$to = substr( $s, $pos + 1);
computexy( $from, $startx, $starty, $colsx, $colsy);
computexy( $to, $x2, $y2, $colsx, $colsy);
$swap = 0;
if (($x2 < $startx) and ($y2 < $starty)) {
$temp = $x2; $x2 = $startx; $startx = $temp;
$temp = $y2; $y2 = $starty; $starty = $temp;
$swap = 1;
}
$movex = $x2 - $startx;
$movey = $y2 - $starty;
/* a*d
*
* b*c
*/
$stamp = $rotate = 0;
if ($movex >= 0 and $movey < 0) {
$letter = 'b';
$file = $dir.'/sa'.$movey.$movex.'.png';
$source = game_imagecreatefrompng( $file);
if ($source != 0) {
$stamp = imagerotate($source, 270, 0);
$starty += $movey; $movey = -$movey;
} else {
$rotate = 270;
}
} else if ($movex < 0 and $movey < 0) {
$letter = 'c';
$file = $dir.'/sa'.$movey.$movex.'.png';
$source = game_imagecreatefrompng( $file);
if ($source != 0) {
$stamp = imagerotate($source, 180, 0);
$startx += $movex; $movex = -$movex;
$starty += $movey; $movey = -$movey;
} else {
$rotate = 180;
}
} else if (($movex < 0) and ($movey >= 0)) {
$letter = 'd';
$file = $dir.'/sa'.$movey.$movex.'.png';
$source = game_imagecreatefrompng( $file);
if ($source != 0) {
$stamp = imagerotate($source, 270, 0);
$startx += $movex; $movex = -$movex;
} else {
$rotate = 270;
}
} else {
$file = $dir.'/sa'.$movex.$movey.'.png';
$stamp = game_imagecreatefrompng( $file);
}
if (($swap != 0) and ($stamp == 0)) {
$temp = $x2; $x2 = $startx; $startx = $temp;
$temp = $y2; $y2 = $starty; $starty = $temp;
$movex = $x2 - $startx;
$movey = $y2 - $starty;
}
$dstx = $startx * $cx / $colsx;
$dsty = $starty * $cy / $colsy;
$dstw = ($movex + 1) * $cx / $colsx;
$dsth = ($movey + 1) * $cy / $colsy;
if ($stamp == 0) {
game_printsnake( $im, $file, $dstx + $ofsleft, $dsty + $ofstop, $dstw, $dsth, $cx / $colsx, $cy / $colsy);
} else {
imagecopyresampled( $im, $stamp, $dstx + $ofsleft, $dsty + $ofstop, 0, 0, $dstw, $dsth,
100 * $movex + 100, 100 * $movey + 100);
}
}
/**
* Image create from png
*
* @param string $file
*/
function game_imagecreatefrompng( $file) {
if (file_exists( $file)) {
return imagecreatefrompng( $file);
}
return 0;
}
/**
* Show number
*
* @param int $imghandle
* @param string $imgnumbers
* @param int $number
* @param int $x1
* @param int $y1
* @param int $width
* @param int $height
* @param int $sizenumbers
*/
function shownumber( $imghandle, $imgnumbers, $number, $x1 , $y1, $width, $height, $sizenumbers) {
if ($number < 10) {
$widthnumber = $sizenumbers[ 0] / 10;
$dstx = $x1 + $width / 10;
$dsty = $y1 + $height / 10;
$srcx = $number * $sizenumbers[ 0] / 10;
$srcw = $sizenumbers[ 0] / 10;
$srch = $sizenumbers[ 1];
$dstw = $width / 10;
$dsth = $dstw * $srch / $srcw;
imagecopyresampled( $imghandle, $imgnumbers, $dstx, $dsty, $srcx, 0, $dstw, $dsth, $srcw, $srch);
} else {
$number1 = floor( $number / 10);
$number2 = $number % 10;
shownumber( $imghandle, $imgnumbers, $number1, $x1 - $width / 20, $y1, $width, $height, $sizenumbers);
shownumber( $imghandle, $imgnumbers, $number2, $x1 + $width / 20, $y1, $width, $height, $sizenumbers);
}
}
/**
* Return rotated point
*
* @param int $x
* @param int $y
* @param int $cx
* @param int $cy
* @param float $a
*/
function returnrotatedpoint($x, $y, $cx, $cy, $a) {
// Radius using distance formula.
$r = sqrt(pow(($x - $cx), 2) + pow(($y - $cy), 2));
// Initial angle in relation to center.
$ia = rad2deg(atan2(($y - $cy), ($x - $cx)));
$nx = $r * cos(deg2rad($a + $ia));
$ny = $r * sin(deg2rad($a + $ia));
return array("x" => $cx + $nx, "y" => $cy + $ny);
}
/**
* Print ladder
*
* @param int $im
* @param string $file
* @param int $x
* @param int $y
* @param int $width
* @param int $height
* @param int $cellx
* @param int $celly
*/
function game_printladder( $im, $file, $x, $y, $width, $height, $cellx, $celly) {
$color = imagecolorallocate($im, 0, 0, 255);
$x2 = $x + $width - $cellx / 2;
$y2 = $y + $height - $celly / 2;
$x1 = $x + $cellx / 2;
$y1 = $y + $celly / 2;
imageline( $im, $x1, $y1, $x2, $y2, $color);
$r = sqrt(pow(($x2 - $x1), 2) + pow(($y2 - $y1), 2));
$mul = 100 / $r;
$x1 = $x2 - ($x2 - $x1) * $mul;
$y1 = $y2 - ($y2 - $y1) * $mul;
$a = returnRotatedPoint( $x1, $y1, $x2, $y2, 20);
imageline( $im, $x2, $y2, $a[ 'x'], $a[ 'y'], $color);
$a = returnRotatedPoint( $x1, $y1, $x2, $y2, -20);
imageline( $im, $x2, $y2, $a[ 'x'], $a[ 'y'], $color);
}
/**
* Print snake
*
* @param int $im
* @param string $file
* @param int $x
* @param int $y
* @param int $width
* @param int $height
* @param int $cellx
* @param int $celly
*/
function game_printsnake( $im, $file, $x, $y, $width, $height, $cellx, $celly) {
$color = imagecolorallocate($im, 0, 255, 0);
$x2 = $x + $width - $cellx / 2;
$y2 = $y + $height - $celly / 2;
$x1 = $x + $cellx / 2;
$y1 = $y + $celly / 2;
imageline( $im, $x1, $y1, $x2, $y2, $color);
$r = sqrt(pow(($x2 - $x1), 2) + pow(($y2 - $y1), 2));
$mul = 100 / $r;
$x2 = $x1 + ($x2 - $x1) * $mul;
$y2 = $y1 + ($y2 - $y1) * $mul;
$a = returnRotatedPoint( $x1, $y1, $x2, $y2, 80);
imageline( $im, $x1, $y1, $a[ 'x'], $a[ 'y'], $color);
$a = returnRotatedPoint( $x1, $y1, $x2, $y2, -80);
imageline( $im, $x1, $y1, $a[ 'x'], $a[ 'y'], $color);
}