[Jeux] Systeme de combat PHP

Petit nouveau ! | 4 Messages

23 avr. 2014, 10:48

Bonjour à Tous :D
Je reprend actuellement le développement d'un de mes ancien site de jeux par navigateur web (www.haishin.fr),
et je suis actuellement bloqué sur l'implémentation du système de combat.
Je souhaitais le faire en C/C++ mais mon hébergeur n'autorise pas les commandes exec(),shell_exec(), etc.. je me suis donc tourné vers PHP :D

J'ai donc commencer une partie du script qui gére aléatoirement la rencontre d'un "Monstre" inscrit dans la DB suivit de 2 options : Combattre ou fuir.
Une fois l'options combattre chosi, le combat se lance, je récupere l"atk" de l'attaquant et la "def" du defenseur selon le tours et applique les dommages, et ce jusqu'à ce que l'un des deux aient des points de vie <= 0. seulement avec le temps j'ai changé d'avis et je souhaite maintenant du tours par tours. je m'explique :
Je souhaite choisir l'option combattre ou fuir. une fois l'options combattre chosie alors :
1er tours Le joueur attaque le monstre,le monstre attaque le joueur.
si 1 des deux pdv <= 0 alors END,
Sinon 2eme tours le joueur RE CHOISI ATTAQUER OU FUIR, le monstre attaque.
etc..
voici le code actuelle :
(petite précision je travaille avec l'outil de template Smarty.)

page de lancement du combat (generation aleatoire d'un monstre)
{if $combat eq ''}
	<p>You've encountered a {$monster}!</p>
	<form action='forest.php' method='post'>
		<input type='submit' name='action' value='Attack' /> or 
		<input type='submit' name='action' value='Run Away' />
		<input type='hidden' name='monster' value='{$monster}' />
	</form>
{else}
	<ul>
	{foreach from=$combat key=id item=i}
		<li><strong>{$i.attacker}</strong> attacks {$i.defender} for {$i.damage} damage!</li>
	{/foreach}
	</ul>
	{if $won eq 1}
		<p>You killed <strong>{$smarty.post.monster}</strong>! You gained <strong>{$earngold}</strong> gold.</p>
		<p><a href='forest.php'>Explore Again</a></p>
	{/if}
	{if $lost eq 1}
		<p>You were killed by <strong>{$smarty.post.monster}</strong>.</p>
	{/if}		
		<p><a href='index.php'>Back to main</a></p>
{/if}

code php
if($_POST) {
	if($_POST['action'] == 'Attack') {
 
		$query = sprintf("SELECT id FROM users WHERE UPPER(username) = UPPER('%s')",
					mysql_real_escape_string($_SESSION['username']));
		$result = mysql_query($query);
		list($userID) = mysql_fetch_row($result);
		$player = array (
			name		=>	$_SESSION['username'],
			attack 		=>	getStat('atk',$userID),
			defence		=>	getStat('def',$userID),
			curhp		=>	getStat('curhp',$userID)
		);
		$query = sprintf("SELECT id FROM monsters WHERE name = '%s'",
					mysql_real_escape_string($_POST['monster']));
		$result = mysql_query($query);
		list($monsterID) = mysql_fetch_row($result);
		$monster = array (
			name		=>	$_POST['monster'],
			attack		=>	getMonsterStat('atk',$monsterID),
			defence		=>	getMonsterStat('def',$monsterID),
			curhp		=>	getMonsterStat('maxhp',$monsterID)
		);
		$combat = array();
		$turns = 0;		
		while($player['curhp'] > 0 && $monster['curhp'] > 0) {
			if($turns % 2 != 0) {
				$attacker = &$monster;
				$defender = &$player;	
			} else {
				$attacker = &$player;
				$defender = &$monster;
			}
			$damage = 0;
			if($attacker['attack'] > $defender['defence']) {
				$damage = $attacker['attack'] - $defender['defence'];	
			}
			$defender['curhp'] -= $damage;
			$combat[$turns] = array(
				attacker	=>	$attacker['name'],
				defender	=>	$defender['name'],
				damage		=>	$damage
			);
			$turns++;
		}
		setStat('curhp',$userID,$player['curhp']);
		if($player['curhp'] > 0) {
			// player won
			setStat('gc',$userID,getStat('gc',$userID)+getMonsterStat('gc',$monsterID));	
			$smarty->assign('won',1);
			$smarty->assign('earngold',getMonsterStat('gc',$monsterID));
			$smarty->assign('gold',getStat('gc',$userID));
		} else {
			// monster won
			$smarty->assign('lost',1);	
		}
		$smarty->assign('combat',$combat);
	} else {
		// Running away!
		header('Location: index.php');	
	}
} else {
	$query = sprintf("SELECT name FROM monsters ORDER BY RAND() LIMIT 1");
	$result = mysql_query($query);
	list($monster) = mysql_fetch_row($result);
	$smarty->assign('monster',$monster);
}
voila pour être clair je bloque ici , exemple concret :
Toi (100 points de vie) - Monstre (10pdv)
Attaque ? fuir ? (action de l'utilisateur)
et puis cette page s'affiche ( le resultat du combat )
Toi attaque monstre pour 5 degats,
Monstre attaque toi pour 2 degats,
Toi attaque Monstre pour 5 degats,
Monstre est mort, tu a gagner.

or je voudrais qu'à chaque fin de 'round' l'utilisateur re-choisi d'attaquer ou fuir :/
un peut comme ça :

Toi (100 points de vie) - Monstre (10pdv)
Attaque ? fuir ? (action de l'utilisateur)
Toi attaque monstre pour 5 degats,
Monstre attaque toi pour 2 degats,

Attaque ? fuir ? (action de l'utilisateur)
Toi attaque Monstre pour 2 degats,
Monstre attaque toi pour 1 degat,

Attaque ? fuir ? (action de l'utilisateur)
Toi attaque Monstre pour 3 degats,
Monstre est mort, tu a gagner.

Mammouth du PHP | 737 Messages

24 avr. 2014, 16:53

Salut,

Tu peux peut être gérer le tout avec des variables de sessions ou des valeurs postées en hidden ?

Ton formulaire peut également être une div cachée qui apparaît au clic...Tu vois le truc ?

Mega
;)
Dyslexics are teople poo

Petit nouveau ! | 4 Messages

24 avr. 2014, 18:36

Tout d'abord... un ENORME merci :D
Je m'explique :
J'arrive maintenant à gérer mon tours par tours avec les variables de sessions.
la seule choses c'est que j'utilise un template smarty, j'ai donc une page php avec le traitement du combat :
if($_POST) {
	if($_POST['action'] == 'Attaque') {
		$smarty->assign('combat',1);
		$smarty->assign('player',$_SESSION['player_name']);
		$smarty->assign('monster',$_SESSION['monster']);
		
				$smarty->assign('monster_initial_HP',$_SESSION['monster_maxhp']);
		$smarty->assign('monster_attack',$_SESSION['monster_attack']);
		$smarty->assign('monster_defence',$_SESSION['monster_defence']);
		
		$damage = $_SESSION['player_attack']-$_SESSION['monster_defence'];
		$_SESSION['monster_curhp'] -= $damage;
		$smarty->assign('monster_damage',$damage);
		$smarty->assign('monster_current_HP',$_SESSION['monster_curhp']);
	} else {
		header('Location: index.php');
	}
} else {
	$query = sprintf("SELECT name FROM monsters ORDER BY RAND() LIMIT 1");
	$result = mysql_query($query);
	list($monster) = mysql_fetch_row($result);
	$smarty->assign('monster',$monster);
	$_SESSION['monster']=$monster;
	$smarty->assign('combat',0);
	
			$query = sprintf("SELECT id FROM users WHERE UPPER(username) = UPPER('%s')",
					mysql_real_escape_string($_SESSION['username']));
		$result = mysql_query($query);
		list($userID) = mysql_fetch_row($result);
		
		$_SESSION['player_name'] = $_SESSION['username'];
		$_SESSION['player_attack'] = getStat('atk',$userID);
		$_SESSION['player_defence'] = getStat('def',$userID);
		$_SESSION['player_curhp'] = getStat('curhp',$userID);
		
		$query = sprintf("SELECT id FROM monsters WHERE name = '%s'",
					mysql_real_escape_string($monster));
		$result = mysql_query($query);
		list($monsterID) = mysql_fetch_row($result);

			$_SESSION['monster_name'] = $_POST['monster'];
			$_SESSION['monster_attack'] = getMonsterStat('atk',$monsterID);
			$_SESSION['monster_defence'] = getMonsterStat('def',$monsterID);
			$_SESSION['monster_curhp'] = getMonsterStat('maxhp',$monsterID);
			$_SESSION['monster_maxhp'] = getMonsterStat('maxhp',$monsterID);
		
		$smarty->assign('monster_initial_HP',$_SESSION['monster_maxhp']);
		$smarty->assign('monster_attack',$_SESSION['monster_attack']);
		$smarty->assign('monster_defence',$_SESSION['monster_defence']);
		$smarty->assign('monster_current_HP',$_SESSION['monster_curhp']);
}

$smarty->display('forest2.tpl');
$smarty->display('navbar.tpl');
et une page de "présentation" smarty :
<p>Tu as rencontré un {$monster} !</p>
		Attaque:{$monster_attack}<br>
		Defence :{$monster_defence}<br>
		HP:{$monster_current_HP} / {$monster_initial_HP}<br>
		<form action='forest2.php' method='post'>
			<input type='submit' name='action' value='Attaque' /> 
			<input type='submit' name='action' value='Fuir' />
			<input type='hidden' name='monster' value='{$monster}' />
		</form>
		
		<ul>
		{if $combat eq 1}
			<li><strong>{$player}</strong> as fait {$monster_damage} dégâts à {$monster} !</li>
		{/if}

		
		</ul>
		{if $won eq 1}
			<p>tu as tué <strong>{$smarty.post.monster}</strong>! tu gagne <strong>{$earngold}</strong> shin.</p>
			<p><a href='forest2.php'>Explorer Encore</a></p>
		{/if}
		{if $lost eq 1}
			<p>Tu as été tué par <strong>{$smarty.post.monster}</strong>.</p>
		{/if}		
		
			<p><a href='index.php'>Retour au jeux</a></p>
	
Et la tout fonctionne exepté une petite chose, je voudrais savoir votre avis la dessus :
Lorsque l'on attaque les valeurs se mettent à jours et l'on peut continuer le combat ou fuir,
une petite phrase s'ajoute disant : XXXX as fait X dégâts à XXXXX !
comme la page se réactualise, une seule phrase apparait, alors que je souhaiterais afficher l'historique du combat.
exemple : www.haishin.fr , id:essai, mdp:essai puis -> http://haishin.fr/forest2.php
essayer vous aller vite comprendre :|
Mon idée est donc de ne pas afficher cette ligne mais afficher un fichier temporaire dans lequels j'ajoute les lignes, donc a chaque re-actualisation, le fichier se complete et on affiche donc les lignes ecrite dans le fichier, est ce propre ? correct ? et sécurisé ?
D'avance merci

Petit nouveau ! | 4 Messages

24 avr. 2014, 20:22

finalement j'ai enregistrer les messages dans la DB avec en id le id unique par combat.
j'aurais juste une dernière choses à demander,
C'est à propos des points d'actions.
Je m'explique : chaque joueurs a 10 PA, chaque actions coute 1PA, jusque là ça va, les PA se regenere disont 1PA chaques heure.
Pour faire simple, j'ai donc implementer tout ça dans une requete SQL appeller dans un script php.
Mon hébergeur n'étant pas très sympa >< il n'autorise pas l'utilisation de crontab.
je suis donc passer par un cron externe (ici : SetCronJob ), seule 'hic' c'est qu'un utilisateur un peu 'vicieux' peut trouver mon script,
par exemple le script PA.php, alors si il vas sur monsite.fr/PA.php .... tadam =D> il incremente les PA de tous les utilisateurs :evil:
=> comment résoudre cette faille de sécurité ?

Mammouth du PHP | 737 Messages

25 avr. 2014, 10:30

Salut,

tu peux peut être gérer le truc par un système de session/jeton ou bien en testant si l'url d'où l'utilisateur vient suit bien le cheminement logique de l'exécution de la page (ou même les 2)

Exemple : l'internaute est sur l'index.php, pour combattre il faut se rendre à la page des combats.php et pa.php intervient ensuite.

L'idée est de dire avec un jeton posté depuis un formulaire puis le système de provenance si tu n'es pas connecté (premièrement), que le jeton passé entre les pages sont différents et que tu ne viens pas de la page combats.php => BYE BYE

Je ne prétends pas que ce soit la meilleure solution mais c'est ce que je peux te proposer et ca devrait marcher ;)

Si quelqu'un a mieux, je/on est preneur :)
Dyslexics are teople poo

Petit nouveau ! | 4 Messages

25 avr. 2014, 11:12

Je me suis peut être mal exprimé :/ ce n'est pas tout à fait là mon problème,
l'histoire du combat est résolu ^^
Ici j'ai un système de Points d'Actions, qui fonctionne, à chaque actions l'utilisateurs perd un PA (aller se soigné, s'entrainer,combattre,etc...)
Jusque là ça fonctionne, le problème c'est pour remplir cette "Barre d'Actions, je voudrais incrementer les PA de +1 chaque heure.
J'ai donc fait une query générique pour tous les utilisateurs (connecté ou non) :
INSERT INTO ma_table_de_stat ('PA') VALUE (PA+1) avec une condition bien sur pour incrementer les user qui n'ont pas le maximum de PA (ce qui evite d'avoir 11/10 PA ;) )
la requête fonctionne, le problème c'est à l'appel du script,
pour le faire periodiquement ... bien sûr, l'accès à crontab m'est interdit par mon hébergeur (ce seras trop facile sinon :P)
j'ai donc fait un script php qui execute cette query et qui est appeller par un cron externe (SetCronJob)
Seulement si quelqu'un lance cette page php il peut lancer cette query :/ ==> grosse faille de sécurité