diff --git a/.gitignore b/.gitignore index a8311f51d..6c6a93367 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ www/*.html -www/*/*.html +www/**/*.html www/css/*.css www/js/index.js www/assets/challenges/descriptors diff --git a/TRANSLATION.md b/TRANSLATION.md new file mode 100644 index 000000000..5787176ed --- /dev/null +++ b/TRANSLATION.md @@ -0,0 +1,50 @@ +# Translation + +Translation files are found in the following directories: +- `lib/challenges/locales`: translation of the challenges +- `locales`: translation of the views +- `content/docs.json`: translation of the documentation + +## i18n not released yet + +Kano OS is not fully i18n-aware and locales are not installed for end users, yet. You can translate this application, but as of now, users will still see the default English message strings. + +## Build + +Translations are part of the normal build process: when you type `npm run build`, the translated challenges and docs will be copied in the `www` directory; and the view templates will be localized by mapping the resources _for each language_. So it means that all resources (views, challenges and docs translations) are prepared in advance. + +## Runtime + +At runtime, the proper translation will be picked based on the browser language. + +## How to add a new translation + +You need to add the new language in 4 places: + +1. Create `lib/challenges/locales/` and copy the whole `worlds` directory and `index.json` + These are the translations of the challenges, the main content of Make-Art. + +2. Create `locales/` and copy the content of `locales/en` + These are the translations of the views + +3. Directly edit `content/docs.json` and add your language to the map (at the top level) + +4. Add your language to `SUPPORTED_LOCALES` array in `lib/i18n.js` + +## How to make sure your code is i18n-aware + +For the challenges, if you create a new challenge in English, there is nothing special to do, it can be translated to other languages by copying the .json file to the other locales directories. + +For the views (jade templates), you need to enclose all your strings in `${{` and `}}$` as this is the convention used by gulp-html-i18n plugin to find and replace the messages in the view templates. Then, you need to add the new string to the corresponding .json file in the (top-level) `locales` directory. Let's say you want to add a string "Happy Birthday" to the challenge.jade template; you would write it as follows in the challenge.jade: `${{ challenge.hapy_birthday }}$`. Then, you would add an entry to the challenge.json map, like: +``` +{ + ... + "happy_birthday": "Happy Birthday" +} +``` + +Finally, for the documentation, if you add / modify text in `content/docs.json` the translations will need to be added for other languages, in the same file. + +## To-Do + +Tool to make it easier to add new languages. diff --git a/content/docs.json b/content/docs.json index 9493c2cb0..a64b82208 100644 --- a/content/docs.json +++ b/content/docs.json @@ -1,4 +1,4 @@ -[ +{ "en": [ { "label" : "Shapes", "icon" : "shapes", @@ -263,6 +263,274 @@ "defaults": [ "black", 50 ] } + ] + } +], "ja" : [ + { + "label" : "形", + "icon" : "shapes", + "commands" : [ + { + "call" : "circle", + "unlockedAt" : 1, + "description" : "円形を描く", + "args" : [ + [ "radius", "number", "円形の大きさ(半径)", true ] + ], + "defaults": [ 100 ] + }, + { + "call" : "ellipse", + "unlockedAt" : 999, + "description" : "楕円を描く", + "args" : [ + [ "radius-x", "number", "楕円の横幅", true ], + [ "radius-y", "number", "楕円の高さ", true ] + ], + "defaults": [ 50, 100 ] + }, + { + "call" : "square", + "unlockedAt" : 2, + "description" : "四角を描く", + "args" : [ + [ "size", "number", "四角の大きさ", true ] + ], + "defaults": [ 200 ] + }, + { + "call" : "rectangle", + "unlockedAt" : 999, + "description" : "長方形を描く", + "args" : [ + [ "width", "number", "長方形の幅", true ], + [ "height", "number", "長方形の高さ", true ] + ], + "defaults": [ 100, 200 ] + }, + { + "call" : "arc", + "unlockedAt" : 999, + "description" : "円形の一部を描く", + "args" : [ + [ "radius", "number", "大きさ(半径)", true ], + [ "start", "number", "開始点(0〜2)", true ], + [ "end", "number", "最後の点(0〜2)", true ], + [ "close", "bool", "形を閉じるかどうか", false ] + ], + "defaults": [ 100, 1, 2, true ] + }, + { + "call" : "polygon", + "unlockedAt" : 999, + "description" : "多辺形を描く", + "args" : [ + [ "x1", "number", "ー点目のX値", true ], + [ "y1", "number", "ー点目のY値", true ], + [ "...", "", "他の点の位置", true ], + [ "close", "bool", "パスを真ん中に閉じるかどうか", false ] + ], + "defaults": [ 0, 0, 100, 0, 100, 100 ] + } + ] + }, + { + "label" : "線", + "icon" : "lines", + "commands" : [ + { + "call" : "line", + "unlockedAt" : 3, + "description" : "ある大きさの線を描く", + "args" : [ + [ "x", "number", "水平距離", true ], + [ "y", "number", "垂直距離", false ] + ], + "defaults": [ 100, 50 ] + }, + { + "call" : "lineTo", + "unlockedAt" : 999, + "description" : "ある点までに線を描く", + "args" : [ + [ "x", "number", "水平の目的点", true ], + [ "y", "number", "垂直の目的点", true ] + ], + "defaults": [ 0, 0 ] + } + ] + }, + { + "label" : "位置", + "icon" : "position", + "commands" : [ + { + "call" : "move", + "unlockedAt" : 6, + "description" : "カーソルをある距離に動かす", + "args" : [ + [ "x", "number", "水平距離", true ], + [ "y", "number", "垂直距離", false ] + ], + "defaults": [ 100, 50 ] + }, + { + "call" : "moveTo", + "unlockedAt" : 999, + "description" : "カーソルをある位置までに動かす", + "args" : [ + [ "x", "number", "水平目的点", true ], + [ "y", "number", "垂直目的点", true ] + ], + "defaults": [ "center", "center" ] + } + ] + }, + { + "label" : "テキスト", + "icon" : "text", + "commands" : [ + { + "call" : "text", + "unlockedAt" : 999, + "description" : "文字を書く", + "args" : [ + [ "message", "string", "メッセージ", true ] + ], + "defaults": [ "何か言って!" ] + }, + { + "call" : "font", + "unlockedAt" : 999, + "description" : "フォントや大きさを設定", + "args" : [ + [ "font", "string", "フォントファミリー名", false ], + [ "size", "number", "ピクセルでのフォントの大きさ", false ] + ], + "defaults": [ "Bariol", 30 ] + }, + { + "call" : "bold", + "unlockedAt" : 999, + "description" : "太字を有効(true)または無効(false)", + "args" : [ + [ "state", "bool", "太字の状態(デフォルトはtrue)", false ] + ], + "defaults": [ true ] + }, + { + "call" : "italic", + "unlockedAt" : 999, + "description" : "車体を有効(true)または無効(false)", + "args" : [ + [ "state", "bool", "車体の状態(デフォルトはtrue)", false ] + ], + "defaults": [ true ] + } + ] + }, + { + "label" : "一般", + "icon" : "general", + "commands" : [ + { + "call" : "for", + "unlockedAt" : 9, + "description" : "コードを繰り返す", + "args" : [ + [ "i in [x..y]", "number", "i変数の最初と最後の値", true ] + ], + "example" : "for i in [1..5]\n circle i", + "defaults": null + }, + { + "call" : "random", + "unlockedAt" : 9, + "description" : "ある範囲内でランダムな数字を生成する", + "args" : [ + [ "min", "number", "最低値", true ], + [ "max", "number", "最高地", true ], + [ "float", "bool", "trueにすると少数が得られる", false ] + ], + "example" : "random 5, 10", + "defaults": [ 5, 10 ] + } + ] + }, + { + "label" : "色", + "icon" : "colors", + "commands" : [ + { + "call" : "background", + "unlockedAt" : 999, + "description" : "背景の色を設定する", + "args" : [ + [ "color", "string", "設定したい背景の色", true ] + ], + "defaults": [ "blue" ] + }, + { + "call" : "color", + "unlockedAt" : 4, + "description" : "鉛筆の色を変える", + "args" : [ + [ "color", "string", "設定したい鉛筆の色", true ] + ], + "defaults": [ "red" ] + }, + { + "call" : "stroke", + "unlockedAt" : 5, + "description" : "筆の太さと色を変える", + "args" : [ + [ "color", "string", "設定したい色。例えば'red', 'blue'..", false ], + [ "size", "number", "鉛筆の太さ", false ] + ], + "defaults": [ 10, "purple" ] + }, + { + "call" : "setBrightness", + "unlockedAt" : 999, + "description" : "色の明るさを設定する", + "args" : [ + [ "color", "string", "色", true ], + [ "amount", "number", "設定したい明るさ(-100〜100)", false ] + ], + "defaults": [ "yellow", 30 ] + }, + { + "call" : "setSaturation", + "unlockedAt" : 999, + "description" : "色の飽和を設定する", + "args" : [ + [ "color", "string", "色", true ], + [ "amount", "number", "設定したい飽和(-100〜100)", false ] + ], + "defaults": [ "grey", 30 ] + }, + { + "call" : "rotate", + "unlockedAt" : 999, + "description" : "色相を回転させる(変更する)", + "args" : [ + [ "color", "string", "変えたい色", true ], + [ "amount", "number", "回転の角度(-360〜360)", true ] + ], + "defaults": [ "red", 100 ] + }, + { + "call" : "setTransparency", + "unlockedAt" : 999, + "description" : "色の透明度を設定する", + "args" : [ + [ "color", "string", "色", true ], + [ "amount", "number", "引き算する不透明度(-100〜100)", true ] + ], + "defaults": [ "black", 50 ] + } + ] } ] +} diff --git a/gulpfile.js b/gulpfile.js index e5aa88250..d624ec2c9 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -13,6 +13,8 @@ var gulp = require('gulp'), griddy = require('griddy'), nib = require('nib'), fs = require('fs'), + i18n = require('gulp-html-i18n'), + del = require('del'), server = lr(), env = process.env.NODE_ENV || 'development', production = env === 'production', @@ -25,12 +27,14 @@ var gulp = require('gulp'), testmode = process.env.TEST_MODE === 'true', chDescriptorsPath = 'www/assets/challenges/descriptors/', libPath = 'lib/challenges/', + locales = ["", "ja"], paths = { views : { watch: ['views/**/*.jade', 'content/**/*'], src: 'views/**/*.jade', out: 'www' }, + viewsi18n : { watch: 'www/**/*.html', src: 'www/**/*.html', out: 'www/locales' }, browserify : { watch: ['lib/**/*', 'content/**/*', 'lib/**/**/*'], src: 'lib/index.js', out: 'www/js' }, styles : { watch: 'styles/**/*.styl', src: 'styles/main.styl', out: 'www/css' }, - content : {watch: 'lib/challenges/**/*'} + content : { watch: 'lib/challenges/**/*' } }; function handleError(error) { @@ -38,174 +42,207 @@ function handleError(error) { } gulp.task('browserify', function () { - gulp.src(paths.browserify.src, { read: false }) - .pipe(browserify({ - transform : [ - partialify.alsoAllow('md'), - partialify.alsoAllow('coffee') - ] - })) - .on('error', handleError) - .pipe(rename('index.js')) - .pipe(gulp.dest(paths.browserify.out)) - .pipe(livereload(server)); + return gulp.src(paths.browserify.src, { read: false }) + .pipe(browserify({ + transform : [ + partialify.alsoAllow('md'), + partialify.alsoAllow('coffee') + ] + })) + .on('error', handleError) + .pipe(rename('index.js')) + .pipe(gulp.dest(paths.browserify.out)) + .pipe(livereload(server)); }); gulp.task('styles', function () { - gulp.src(paths.styles.src) - .pipe(stylus({ - pretty : !production, - use : [griddy(), nib()] - })) - .on('error', handleError) - .pipe(gulp.dest(paths.styles.out)) - .pipe(livereload(server)); + return gulp.src(paths.styles.src) + .pipe(stylus({ + pretty : !production, + use : [griddy(), nib()] + })) + .on('error', handleError) + .pipe(gulp.dest(paths.styles.out)) + .pipe(livereload(server)); }); gulp.task('views', function () { - gulp.src(paths.views.src) - .pipe(jade({ - pretty : !production, - locals : _.extend({ - env : env, - production : production, - offline : offline, - segmentioId : segmentioId, - facebookAppId : facebookAppId, - api_url : api_url, - world_url : world_url, - testmode : testmode, - challenges_url : "/assets/challenges/descriptors", - unknown_user : unknown_user - }, jadeHelpers) - })) - .on('error', handleError) - .pipe(gulp.dest(paths.views.out)) - .pipe(livereload(server)); + return gulp.src(paths.views.src) + .pipe(jade({ + pretty : !production, + locals : _.extend({ + env : env, + production : production, + offline : offline, + segmentioId : segmentioId, + facebookAppId : facebookAppId, + api_url : api_url, + world_url : world_url, + testmode : testmode, + challenges_url : "/assets/challenges/descriptors", + unknown_user : unknown_user + }, jadeHelpers) + })) + .on('error', handleError) + .pipe(gulp.dest(paths.views.out)) + .pipe(livereload(server)); +}); + +gulp.task('clean-i18n', function (next) { + del([paths.viewsi18n.out], next); +}); + +gulp.task('views-i18n', ['clean-i18n', 'views'], function () { + return gulp.src(paths.viewsi18n.src) + .pipe(i18n({ langDir: './locales', + createLangDirs: true })) + .on('error', handleError) + .pipe(gulp.dest(paths.viewsi18n.out)) + .pipe(livereload(server)); }); /** - * This task modifies the challenge index to contain basic - * information about the single challenges, so that we - * can show a calendar without loading all the single challenges. + * This function returns a function that modifies the challenge + * index to contain basic information about the single challenges, + * so that we can show a calendar without loading all the single + * challenges. + * The returned function will be called for each locale. */ -gulp.task('apify-challenges', ['copy-challenges'], function (next) { - var index, - worldsNum, - //fields that are copied from ./index.json to /world//index.json - copyWorldFields = [ - 'id', - 'name', - 'description', - 'world_path', - 'cover', - 'css_class', - 'visibility', - 'dependency', - 'type', - 'share_strategy', - 'sales_popup_after', - 'certificate_after', - 'teachers_guide', - 'updateForm', - 'socialText' - ], - countNext = 0, - formattedIndex; - function localNext() { - if (++countNext === worldsNum + 1) { - next(); - } - } - //work with them - index = require('./' + chDescriptorsPath + 'index.json'); - worldsNum = index.worlds.length; - - index.worlds.forEach(function (world) { - var worldPath = './' + chDescriptorsPath + world.world_path, - libWorldPath = './' + libPath + world.world_path, - worldObj = {}, - challenges = [], - formattedJSON; - - worldObj = JSON.parse(JSON.stringify(require(libWorldPath + '/index.json'))); - - copyWorldFields.forEach(function (field) { - if (world[field]) { - worldObj[field] = world[field]; +function apifyChallengeFn(next) { + return function (locale) { + + var index, + worldsNum, + //fields that are copied from ./index.json to /world//index.json + copyWorldFields = [ + 'id', + 'name', + 'description', + 'world_path', + 'cover', + 'css_class', + 'visibility', + 'dependency', + 'type', + 'share_strategy', + 'sales_popup_after', + 'certificate_after', + 'teachers_guide', + 'updateForm', + 'socialText' + ], + countNext = 0, + formattedIndex, + localePath = locale ? 'locales/' + locale + '/' : ''; + function localNext() { + if (++countNext === worldsNum + 1) { + next(); } - }); + } + //work with them + index = require('./' + chDescriptorsPath + localePath + 'index.json'); + worldsNum = index.worlds.length; - //load all the challenges in an array - worldObj.challenges.forEach(function (ch, idx, arr) { - var chFileName = worldPath + ch.substr(1, ch.length - 1), - challenge = require(chFileName), - index = idx + 1, - hasNext = index !== (arr.length), - ch_obj = { - id: challenge.id, - title: challenge.title, - short_title: challenge.short_title, - cover: challenge.cover, - index: index, - hasNext: hasNext, - start_date: challenge.start_date - }; - challenge.index = index ; - challenge.hasNext = hasNext; - - fs.writeFile(chFileName + ".json", JSON.stringify(challenge, null, 4), function (err) { - if (err) { - throw err; + index.worlds.forEach(function (world) { + var worldPath = './' + chDescriptorsPath + localePath + world.world_path, + libWorldPath = './' + libPath + localePath + world.world_path, + worldObj = {}, + challenges = [], + formattedJSON; + + worldObj = JSON.parse(JSON.stringify(require(libWorldPath + '/index.json'))); + + copyWorldFields.forEach(function (field) { + if (world[field]) { + worldObj[field] = world[field]; } }); - challenges.push(ch_obj); - }); + + //load all the challenges in an array + worldObj.challenges.forEach(function (ch, idx, arr) { + var chFileName = worldPath + ch.substr(1, ch.length - 1), + challenge = require(chFileName), + index = idx + 1, + hasNext = index !== (arr.length), + ch_obj = { + id: challenge.id, + title: challenge.title, + short_title: challenge.short_title, + cover: challenge.cover, + index: index, + hasNext: hasNext, + start_date: challenge.start_date + }; + challenge.index = index ; + challenge.hasNext = hasNext; + + fs.writeFile(chFileName + ".json", JSON.stringify(challenge, null, 4), function (err) { + if (err) { + throw err; + } + }); + challenges.push(ch_obj); + }); - worldObj.challenges = challenges; + worldObj.challenges = challenges; - world.challenges_num = challenges.length; + world.challenges_num = challenges.length; - formattedJSON = JSON.stringify(worldObj, null, 4); - //write the challenges with headers - fs.writeFile(worldPath + '/index.json', formattedJSON, function (err) { + formattedJSON = JSON.stringify(worldObj, null, 4); + //write the challenges with headers + fs.writeFile(worldPath + '/index.json', formattedJSON, function (err) { + if (err) { + throw err; + } else { + localNext(); + } + }); + }); + //copy back the index + formattedIndex = JSON.stringify(index, null, 4); + fs.writeFile(chDescriptorsPath + localePath + 'index.json', formattedIndex, function (err) { if (err) { throw err; } else { localNext(); } }); - }); - //copy back the index - formattedIndex = JSON.stringify(index, null, 4); - fs.writeFile(chDescriptorsPath + 'index.json', formattedIndex, function (err) { - if (err) { - throw err; - } else { - localNext(); - } - }); + } +} +gulp.task('apify-challenges', ['copy-challenges'], function (next) { + var countNext = 0; + function localNext() { + if (++countNext === locales.length) { + next(); + } + } + + locales.forEach(apifyChallengeFn(localNext)); }); gulp.task('copy-challenges', function (next) { var counter = 0, stream1, - stream2; + stream2, + stream3; function localNext() { - if (++counter === 2) { + if (++counter === 3) { next(); } } + //copy the files stream1 = gulp.src('lib/challenges/worlds/**/*.json') .pipe(gulp.dest(chDescriptorsPath + "/worlds")); - //copy the files stream2 = gulp.src('lib/challenges/index.json') .pipe(gulp.dest(chDescriptorsPath)); + stream3 = gulp.src('lib/challenges/locales/**/*.json') + .pipe(gulp.dest(chDescriptorsPath + "/locales")); stream1.on('end', localNext); stream2.on('end', localNext); + stream3.on('end', localNext); }); @@ -221,7 +258,7 @@ gulp.task('listen', function (next) { }); gulp.task('prepare-challenges', ['copy-challenges', 'apify-challenges']); -gulp.task('build', ['browserify', 'styles', 'views', 'prepare-challenges']); +gulp.task('build', ['browserify', 'styles', 'views-i18n', 'prepare-challenges']); gulp.task('watch', ['build', 'listen'], function () { gulp.watch(paths.browserify.watch, ['browserify']); diff --git a/lib/app.js b/lib/app.js index 748f31328..160630cf9 100644 --- a/lib/app.js +++ b/lib/app.js @@ -5,7 +5,7 @@ * Define behaviour for app `run` and `config` */ -var api, auth, cfg, envCfg, tracking, +var api, auth, cfg, envCfg, config = require('./core/config'), analytics = require('./core/analytics'), app = angular.module('draw', ['ngRoute']), @@ -21,7 +21,6 @@ envCfg = { auth = require('./core/auth')(envCfg); api = require('./api')(envCfg); -tracking = require('./core/tracking'); window.CONFIG = cfg; domainCfg = cfg.DOMAIN_CFG; @@ -134,12 +133,14 @@ app.run(function ($rootScope, $window) { openModal: function () { this.showModal = true; }, closeModal: function () { this.showModal = false; } }; + $rootScope.feedback = { + showModal: false, + openModal: function () { this.showModal = true; }, + closeModal: function () { this.showModal = false; } + }; initProgress(); - - tracking.init(); - // Initialised auth state auth.init(function () { var userObj, userId; diff --git a/lib/challenges/locales/ja/index.json b/lib/challenges/locales/ja/index.json new file mode 100644 index 000000000..d5083d36b --- /dev/null +++ b/lib/challenges/locales/ja/index.json @@ -0,0 +1,71 @@ +{ + "worlds": [ + { + "id": "basic", + "name": "初級", + "description": "このチャレンジを通して、メークアートの基礎を身につけよう", + "cover": "world_covers/basic", + "world_path": "worlds/basic", + "css_class": "basic-challenges", + "share_strategy": "optional", + "type": "normal" + + }, + { + "id": "medium", + "name": "中級", + "description": "中級向けのチャレンジ", + "cover": "world_covers/medium", + "world_path": "worlds/medium", + "css_class": "medium", + "dependency": ["basic"], + "share_strategy": "optional", + "type": "normal" + }, + { + "id": "pixelhack", + "name": "ピクセル・ハック", + "description": "ハウアー・オブ・コード用のチャレンジです", + "cover": "world_covers/pixelhack", + "world_path": "worlds/pixelhack", + "css_class": "pixelhack", + "type": "campaign", + "certificate_after": 2, + "teachers_guide": "/guides/PixelHackEducatorGuide.zip", + "share_strategy": "optional", + "updateForm": { + "url": "https://docs.google.com/forms/d/1nTJ-waAVLQCO3myxKMDQLafL5Fnf9uTPtiejuH-74sY/formResponse", + "field": "entry.1965349241" + }, + "socialText": { + "email": "Kanoのピクセルハックで、ビデオゲームのアート歴史をハックしよう。", + "facebook": "Kanoの #ピクセルハック で、ビデオゲームのアート歴史をハックしよう。", + "twitter": "@TeamKano の #ピクセルハック で、ビデオゲームのアート歴史をハックしよう!\nhttp://art.kano.me/challenges/pixelhack/" + } + }, + { + "id": "summercamp", + "name": "夏キャンプ", + "description": "このチャレンジを通して、メークアートの基礎を身につけよう", + "cover": "world_covers/summercamp", + "world_path": "worlds/summercamp", + "css_class": "_summercamp", + "dependency": ["medium"], + "share_strategy": "optional", + "type": "campaign" + + }, + { + "id": "mischiefweek2015", + "name": "いたずらの週", + "description": "ハロウィーン専用の世界です", + "cover": "world_covers/mischiefweek", + "world_path": "worlds/mischiefweek2015", + "start_date": "2015-10-26T06:00:00", + "css_class": "mischiefweek2015", + "type": "campaign", + "share_strategy": "optional", + "sales_popup_after": 2 + } + ] +} diff --git a/lib/challenges/locales/ja/worlds/basic/baloon.json b/lib/challenges/locales/ja/worlds/basic/baloon.json new file mode 100644 index 000000000..122d81caa --- /dev/null +++ b/lib/challenges/locales/ja/worlds/basic/baloon.json @@ -0,0 +1,42 @@ +{ + "id": "baloon", + "title": "青い風船", + "cover": "blue-baloon.png", + "description": "多辺形で空を飛ぶ風船を描こう!", + "startAt": 2, + "steps": [ + { + "hint": "鉛筆の色を青に変えよう。`color blue`を**タイプ**", + "solution": "color blue" + }, + { + "hint": "筆の幅を0にして、線を描かないようにしよう。", + "solution": "stroke 0" + }, + { + "hint": "100の大きさの円形を描こう。", + "solution": "circle 100" + }, + { + "hint": "100歩で下に動こう。`move 0, 100`を**タイプ**", + "solution": "move 0, 100" + }, + { + "hint": "結び目を描こう。`polygon 15, 15, -15, 15`を**タイプ**", + "solution": "polygon 15, 15, -15, 15" + }, + { + "hint": "もう少し下に動こう。`move 0, 15`を**タイプ**", + "solution": "move 0, 15" + }, + { + "hint": "太くて黒い筆を選ぼう。`stroke black, 5`を**タイプ**", + "solution": "stroke black, 5" + }, + { + "hint": "風船の糸を描こう。`line 0, 200`を**タイプ**", + "solution": "line 0, 200" + } + ], + "completion_text": "素晴らしい風船!次に進む前に色を変えてみない?" +} diff --git a/lib/challenges/locales/ja/worlds/basic/breakfast.json b/lib/challenges/locales/ja/worlds/basic/breakfast.json new file mode 100644 index 000000000..b42d3d54d --- /dev/null +++ b/lib/challenges/locales/ja/worlds/basic/breakfast.json @@ -0,0 +1,197 @@ +{ + "id": "breakfast", + "title": "Breakfast", + "description": "Draw a bacon and eggs breakfast!", + "startAt": 2, + "fatherDay": true, + "steps": [ + { + "hint": "Set the background to blue - **type** `background blue`", + "solution": "background blue" + }, + { + "hint": "Set the stroke to 0, to avoid drawing lines", + "solution": "stroke 0" + }, + { + "hint": "Set the color to white", + "solution": "color white" + }, + { + "hint": "Draw a circle with a size of 240", + "solution": "\n#Plate\ncircle 240", + "validate": "circle 240" + }, + { + "hint": "Set the color to `'#eee'` - **type** `color '#eee'`", + "solution": "color '#eee'" + }, + { + "hint": "Draw a circle with a size of 200", + "solution": "circle 200" + }, + { + "hint": "Move up and left - **type** `move -70, -70`", + "solution": "\n#Egg\nmove -70, -70", + "validate": "move -70,-70" + }, + { + "hint": "Set the color to white", + "solution": "color white" + }, + { + "hint": "Draw a circle with a size of 80", + "solution": "circle 80" + }, + { + "hint": "Set the color to yellow", + "solution": "color yellow" + }, + { + "hint": "Draw a circle with a size of 30", + "solution": "circle 30" + }, + { + "hint": "Move up and right - **type** `move 90, -60`", + "solution": "\n#Bacon 1\nmove 90, -60", + "validate": "move 90,-60" + }, + { + "hint": "Set the color to red", + "solution": "color red" + }, + { + "hint": "Draw a rectangle with a size of 60 and 200 - **type** `rectangle 60, 200`", + "solution": "rectangle 60, 200" + }, + { + "hint": "Move 30 to the right - **type** `move 30`", + "solution": "move 30" + }, + { + "hint": "Set the color to `'#aa0000'` - **type** `color '#aa0000'`", + "solution": "color '#aa0000'" + }, + { + "hint": "Draw a rectangle with a size of 30 and 200 - **type** `rectangle 30, 200`", + "solution": "rectangle 30, 200" + }, + { + "hint": "Move down and left - **type** `move -3, 10`", + "solution": "move -3, 10" + }, + { + "hint": "Set the color to white", + "solution": "color white" + }, + { + "hint": "Draw a rectangle with a size of 6 and 180 - **type** `rectangle 6, 180`", + "solution": "rectangle 6, 180" + }, + { + "hint": "Move down and right - **type** `move 40, 50`", + "solution": "\n#Bacon 2\nmove 40, 50", + "validate": "move 40, 50" + }, + { + "hint": "Set the color to red", + "solution": "color red" + }, + { + "hint": "Draw a rectangle with a size of 60 and 200 - **type** `rectangle 60, 200`", + "solution": "rectangle 60, 200" + }, + { + "hint": "Move 30 to the right - **type** `move 30`", + "solution": "move 30" + }, + { + "hint": "Set the color to `'#aa0000'` - **type** `color '#aa0000'`", + "solution": "color '#aa0000'" + }, + { + "hint": "Draw a rectangle with a size of 30 and 200 - **type** `rectangle 30, 200`", + "solution": "rectangle 30, 200" + }, + { + "hint": "Move down and left - **type** `move -3, 10`", + "solution": "move -3, 10" + }, + { + "hint": "Set the color to white", + "solution": "color white" + }, + { + "hint": "Draw a rectangle with a size of 6 and 180 - **type** `rectangle 6, 180`", + "solution": "rectangle 6, 180" + }, + { + "hint": "Move down and left - **type** `move -200, 150`", + "solution": "\n#Tomato 1\nmove -200, 150", + "validate": "move -200, 150" + }, + { + "hint": "Set the color to red", + "solution": "color red" + }, + { + "hint": "Draw a circle with a size of 40", + "solution": "circle 40" + }, + { + "hint": "Set the color to `'#cc4444'` - **type** `color '#cc4444'`", + "solution": "color '#cc4444'" + }, + { + "hint": "Draw a circle with a size of 35", + "solution": "circle 35" + }, + { + "hint": "Set the color to `'#aa4444'` - **type** `color '#aa4444'`", + "solution": "color '#aa4444'" + }, + { + "hint": "Draw an ellipse with a size of 30 and 10", + "solution": "ellipse 30, 10" + }, + { + "hint": "Draw an ellipse with a size of 10 and 30", + "solution": "ellipse 10, 30" + }, + { + "hint": "Move down and right - **type** `move 70, 50`", + "solution": "\n#Tomato 2\nmove 70, 50", + "validate": "move 70, 50" + }, + { + "hint": "Set the color to red", + "solution": "color red" + }, + { + "hint": "Draw a circle with a size of 40", + "solution": "circle 40" + }, + { + "hint": "Set the color to `'#cc4444'` - **type** `color '#cc4444'`", + "solution": "color '#cc4444'" + }, + { + "hint": "Draw a circle with a size of 35", + "solution": "circle 35" + }, + { + "hint": "Set the color to `'#aa4444'` - **type** `color '#aa4444'`", + "solution": "color '#aa4444'" + }, + { + "hint": "Draw an ellipse with a size of 30 and 10", + "solution": "ellipse 30, 10" + }, + { + "hint": "Draw an ellipse with a size of 10 and 30", + "solution": "ellipse 10, 30" + } + ], + "completion_text": "Well done!", + "cover": "breakfast.png" +} \ No newline at end of file diff --git a/lib/challenges/locales/ja/worlds/basic/index.json b/lib/challenges/locales/ja/worlds/basic/index.json new file mode 100644 index 000000000..2369ad6ca --- /dev/null +++ b/lib/challenges/locales/ja/worlds/basic/index.json @@ -0,0 +1,11 @@ +{ + "challenges": [ + "./sunnyday", + "./swissflag", + "./stare", + "./smiley", + "./baloon", + "./stickman" + + ] +} diff --git a/lib/challenges/locales/ja/worlds/basic/smiley.json b/lib/challenges/locales/ja/worlds/basic/smiley.json new file mode 100644 index 000000000..b92e8d918 --- /dev/null +++ b/lib/challenges/locales/ja/worlds/basic/smiley.json @@ -0,0 +1,50 @@ +{ + "id": "smiley", + "title": "初めての笑顔", + "description": "顔を描こう", + "startAt": 2, + "steps": [ + { + "hint": "鉛筆の色を黄色に変えよう。`color yellow`を**タイプ**", + "solution": "color yellow" + }, + { + "hint": "太くて黒い筆を選ぼう。`stroke black, 20`を**タイプ**", + "solution": "stroke black, 20" + }, + { + "hint": "200の大きさの丸を描こう", + "solution": "circle 200" + }, + { + "hint": "左上を80歩ずつ動こう。`move -80, -80`を**タイプ**", + "solution": "move -80, -80" + }, + { + "hint": "鉛筆の色を黒にしよう。", + "solution": "color black" + }, + { + "hint": "半径20の丸を描こう。", + "solution": "circle 20" + }, + { + "hint": "160歩右へ動こう。`move 160`を**タイプ**", + "solution": "move 160" + }, + { + "hint": "半径20の丸をもう一つ描こう。", + "solution": "circle 20" + }, + { + "hint": "中央と下まで動こう。次の行で`moveTo 250, 270`を**タイプ**", + "solution": "moveTo 250, 270" + }, + { + "hint": "アーク(円弧)は丸の一部で、口に一つ描けば良さそう。`arc 100, 1, 2`を**タイプ**", + "solution": "arc 100, 1, 2" + } + ], + "completion_text": "よくやった!その調子で、笑顔描きジーニャスさん!", + "cover": "smiley.png" +} diff --git a/lib/challenges/locales/ja/worlds/basic/stare.json b/lib/challenges/locales/ja/worlds/basic/stare.json new file mode 100644 index 000000000..4f502b635 --- /dev/null +++ b/lib/challenges/locales/ja/worlds/basic/stare.json @@ -0,0 +1,55 @@ +{ + "id": "stare", + "title": "暗やみでじろじろ", + "description": "暗やみでジロジロ見つめる目を描きましょう", + "startAt": 2, + "steps": [ + { + "hint": "背景を黒(black)にしましょう", + "solution": "background black" + }, + { + "hint": "左に80歩動こう。`move -80`を**タイプ**", + "solution": "move -80", + "validate": "move -80" + }, + { + "hint": "鉛筆の色を白(white)に変えよう", + "solution": "color white" + }, + { + "hint": "楕円を描こう。伸ばした円形のように。`ellipse 60, 40`を**タイプ**", + "solution": "ellipse 60, 40" + }, + { + "hint": "鉛筆の色を黒に変えよう。`color black`を**タイプ**", + "solution": "color black" + }, + { + "hint": "大きさ10の丸を描こう。`circle 10`を**タイプ**", + "solution": "circle 10" + }, + { + "hint": "160歩右側に動こう。`move 160`を**タイプ**", + "solution": "move 160" + }, + { + "hint": "また鉛筆の色を白に変えよう。", + "solution": "color white" + }, + { + "hint": "もう一つの幅60で高さ40の楕円を描こう。`ellipse 60, 40`を**タイプ**", + "solution": "ellipse 60, 40" + }, + { + "hint": "鉛筆の色を黒に変えよう。", + "solution": "color black" + }, + { + "hint": "10の大きさの丸を描いて、できあがり!", + "solution": "circle 10" + } + ], + "completion_text": "本当の魔法使いだ!またジロジロ見つめる目を描きたかったら君に頼むよ!", + "cover": "stare.png" +} diff --git a/lib/challenges/locales/ja/worlds/basic/stickman.json b/lib/challenges/locales/ja/worlds/basic/stickman.json new file mode 100644 index 000000000..5e5f20c52 --- /dev/null +++ b/lib/challenges/locales/ja/worlds/basic/stickman.json @@ -0,0 +1,54 @@ +{ + "id": "stickman", + "title": "棒人間", + "description": "円形と線で棒人間を描こう", + "startAt": 2, + "steps": [ + { + "hint": "筆(`stroke`)の色を黒(`black`)に、幅を`10`に設定しよう", + "solution": "stroke black, 10" + }, + { + "hint": "カーソルを動かそう。`move 0, -50`を**タイプ**", + "solution": "move 0, -50" + }, + { + "hint": "棒人間の体を描こう。`line 0, 150`", + "solution": "line 0, 150" + }, + { + "hint": "棒人間の左腕を描こう。`line -80, 120`", + "solution": "line -80, 120" + }, + { + "hint": "よっし、次は右腕を。`line 80, 120`", + "solution": "line 80, 120" + }, + { + "hint": "下へ行こう。`move 0, 150`を**タイプ**", + "solution": "move 0, 150" + }, + { + "hint": "棒人間の左足を描こう:`line -80, 120`", + "solution": "line -80, 120" + }, + { + "hint": "よっし、次は右足を:`line 80, 120`", + "solution": "line 80, 120" + }, + { + "hint": "絵の上に動こう。`moveTo 250, 100`を**タイプ**", + "solution": "moveTo 250, 100" + }, + { + "hint": "筆の太さを0に戻そう。", + "solution": "stroke 0" + }, + { + "hint": "最後に、多変形で頭を描こう。`polygon -60, 50, 0, 100, 60, 50`を**タイプ**", + "solution": "polygon -60, 50, 0, 100, 60, 50" + } + ], + "completion_text": "良くできました!絵の高さと幅は500ピクセルずつで、正しく動くことは難しい。", + "cover": "stickman.png" +} diff --git a/lib/challenges/locales/ja/worlds/basic/sunnyday.json b/lib/challenges/locales/ja/worlds/basic/sunnyday.json new file mode 100644 index 000000000..97ec66720 --- /dev/null +++ b/lib/challenges/locales/ja/worlds/basic/sunnyday.json @@ -0,0 +1,23 @@ +{ + "id": "sunnyday", + "title": "晴れの日", + "description": "晴れの日をコードで表して、基礎を覚えよう。", + "code": "", + "startAt": 2, + "steps": [ + { + "hint": "まず、背景をきれいな空色で塗りましょう。- `background blue`を**タイプ**", + "solution": "background blue" + }, + { + "hint": "次は、鉛筆の色を明るい黄色に変えよう。- 次の行に`color yellow`を**タイプ**", + "solution": "color yellow" + }, + { + "hint": "最後に、「circle」(円型)コマンドで、太陽を描こう。円の大きさを数字で表そう。- 次の行に`circle 150`を**タイプ**", + "solution": "circle 150" + } + ], + "completion_text": "おめでとう!さっぱりした晴れの日ができた。次に、円の大きさを変えて、どうなるか確認して見よう。", + "cover": "sunny-day.png" +} diff --git a/lib/challenges/locales/ja/worlds/basic/swissflag.json b/lib/challenges/locales/ja/worlds/basic/swissflag.json new file mode 100644 index 000000000..d440e5186 --- /dev/null +++ b/lib/challenges/locales/ja/worlds/basic/swissflag.json @@ -0,0 +1,39 @@ +{ + "id": "swissflag", + "title": "スイスの国旗", + "description": "スイスの国旗をコードで作ろう", + "code": "", + "startAt": 2, + "steps": [ + { + "hint": "もう少し難しいチャレンジ。まず、壁紙を塗ろう:`background red`を**タイプ**", + "solution": "background red" + }, + { + "hint": "これから太い線を描くので、筆の太さを変えよう。`stroke 66`を**タイプ**", + "solution": "stroke 66" + }, + { + "hint": "次に筆の色を白に変えよう。3行目に`stroke white`を**タイプ**", + "solution": "stroke white" + }, + { + "hint": "最初の線を描いてみよう。線の色は白で、幅は66ピクセルに設定済み。では、100ピクセルの線を描いてみよう:`line 100`を**タイプ**", + "solution": "line 100" + }, + { + "hint": "短くて丈夫な線ができた!もう一本必要。次も100ピクセルの長さだけど、反対方向に。`line -100`を**タイプ**", + "solution": "line -100" + }, + { + "hint": "いいね!次は上下の線も描かなきゃ。どうしたらいいかね?実は「line」(線)に2つの数字を入れられる。一つ目は左右の位置で、2つ目は上下の位置。`line 0, 100`を**タイプ**", + "solution": "line 0, 100" + }, + { + "hint": "線は下に向いてるね!次は上へ行くには`line 0, -100`を**タイプ**", + "solution": "line 0, -100" + } + ], + "completion_text": "素晴らしい国旗ができた!シンプルなデザインはスイスの特徴だ。", + "cover": "swissflag.png" +} diff --git a/lib/challenges/locales/ja/worlds/medium/dots.json b/lib/challenges/locales/ja/worlds/medium/dots.json new file mode 100644 index 000000000..aa4798975 --- /dev/null +++ b/lib/challenges/locales/ja/worlds/medium/dots.json @@ -0,0 +1,40 @@ +{ + "id": "dots", + "title": "水玉模様", + "description": "ループと丸を使って、可愛い水玉模様を描こう。", + "code": "", + "startAt": 1, + "steps": [ + { + "hint": "背景を赤(`red`)にしよう。", + "solution": "background red" + }, + { + "hint": "筆の幅を0にしよう。", + "solution": "stroke 0" + }, + { + "hint": "色を黄色(`yellow`)にしよう。", + "solution": "color yellow" + }, + { + "hint": "次はループを始めよう。`for x in [ 0 .. 25 ]`を**タイプ**", + "solution": "for x in [ 0..25 ]" + }, + { + "hint": "ループの中にはもう一つのループを。`for y in [ 0 .. 25 ]`を**タイプ**", + "solution": " for y in [ 0..25 ]" + }, + { + "hint": "縦と横へ動こう。`moveTo x * 20, y * 20`を**タイプ**", + "solution": " moveTo x * 20, y * 20", + "validate": " moveTo x *\\* *20,y *\\* *20" + }, + { + "hint": "そして水玉を描こう。`circle 6`を**タイプ**", + "solution": " circle 6" + } + ], + "completion_text": "できた!数字を変えて、どうなるか見てみよう。", + "cover": "dots.png" +} diff --git a/lib/challenges/locales/ja/worlds/medium/gradient.json b/lib/challenges/locales/ja/worlds/medium/gradient.json new file mode 100644 index 000000000..d9e1b60ff --- /dev/null +++ b/lib/challenges/locales/ja/worlds/medium/gradient.json @@ -0,0 +1,33 @@ +{ + "id": "gradient", + "title": "虹のパレット", + "description": "ループと色を組み合わせ、魔法の絵を!", + "code": "", + "startAt": 1, + "steps": [ + { + "hint": "まず、forループを始めよう。`for x in [ 0 .. 25 ]`を**タイプ**", + "solution": "for x in [ 0..25 ]" + }, + { + "hint": "次は2つ目のforループを始めよう。`for y in [ 0 .. 25 ]`を**タイプ**", + "solution": " for y in [ 0..25 ]" + }, + { + "hint": "色のトーンを回転させよう。`color rotate red, 10 * x + 10 * y`を**タイプ**", + "solution": " color rotate red, 10 * x + 10 * y", + "validate": " color rotate +red,10 *\\* *x *\\+ *10 *\\* *y" + }, + { + "hint": "そして描くときに毎回動かなきゃ。`moveTo 20 * x, 20 * y`を**タイプ**", + "solution": " moveTo 20 * x, 20 * y", + "validate": " moveTo 20 *\\* *x,20 *\\* *y" + }, + { + "hint": "最後に大きさ20の四角を描こう。", + "solution": " square 20" + } + ], + "completion_text": "回転(rotate)で数字を変えると、どうなるんだろう?", + "cover": "gradient.png" +} diff --git a/lib/challenges/locales/ja/worlds/medium/house.json b/lib/challenges/locales/ja/worlds/medium/house.json new file mode 100644 index 000000000..3a786977e --- /dev/null +++ b/lib/challenges/locales/ja/worlds/medium/house.json @@ -0,0 +1,87 @@ +{ + "id": "house", + "title": "家", + "description": "居心地のよい家を描こう!", + "code": "", + "startAt": 1, + "steps": [ + { + "hint": "まず空を描こう!背景を青(`blue`)に設定しよう。", + "solution": "background blue" + }, + { + "hint": "筆の幅を0にしよう。", + "solution": "stroke 0" + }, + { + "hint": "左上へ動こう。`move -150, -50`を**タイプ**", + "solution": "move -150, -50" + }, + { + "hint": "色をベージュ(`beige`)にしよう。", + "solution": "color beige" + }, + { + "hint": "次は長方形を描こう。`rectangle 300, 200`を**タイプ**", + "solution": "rectangle 300, 200" + }, + { + "hint": "右上へ動こう。`move 150, -100`を**タイプ**", + "solution": "move 150, -100" + }, + { + "hint": "屋根には色を暗赤色(`darkred`)にしよう。", + "solution": "color darkred" + }, + { + "hint": "次は屋根を描こう。`polygon 170, 100, -170, 100`を**タイプ**", + "solution": "polygon 170, 100, -170, 100" + }, + { + "hint": "左下へ動こう。`move -250, 300`を**タイプ**", + "solution": "move -250, 300" + }, + { + "hint": "芝生を描くには色を緑(`green`)に設定しよう。", + "solution": "color green" + }, + { + "hint": "次は芝生を500, 100の長方形(`rectangle`)で描こう。", + "solution": "rectangle 500, 100" + }, + { + "hint": "右上へ動こう。`move 220, -80`を**タイプ**", + "solution": "move 220, -80" + }, + { + "hint": "木のドアの色を茶色(`brown`)に設定しよう。", + "solution": "color brown" + }, + { + "hint": "ドアを60, 80の長方形で描こう。", + "solution": "rectangle 60, 80" + }, + { + "hint": "窓の色を水色(`aqua`)に設定しよう。", + "solution": "color aqua" + }, + { + "hint": "左上へ動こう。`move -80, -80`を**タイプ**", + "solution": "move -80, -80" + }, + { + "hint": "50の四角を描こう。", + "solution": "square 50" + }, + { + "hint": "右へ行こう。`move 170`を**タイプ**", + "solution": "move 170" + }, + { + "hint": "50の四角を描こう。", + "solution": "square 50" + } + ], + "completion_text": "すごい家をコードで描いた!", + "cover": "house.png" +} diff --git a/lib/challenges/locales/ja/worlds/medium/index.json b/lib/challenges/locales/ja/worlds/medium/index.json new file mode 100644 index 000000000..6d4e6623b --- /dev/null +++ b/lib/challenges/locales/ja/worlds/medium/index.json @@ -0,0 +1,13 @@ +{ + "challenges": [ + "./shrinking", + "./random", + "./starry", + "./house", + "./dots", + "./gradient", + "./planet", + "./pizza" + ] +} + diff --git a/lib/challenges/locales/ja/worlds/medium/pizza.json b/lib/challenges/locales/ja/worlds/medium/pizza.json new file mode 100644 index 000000000..592049006 --- /dev/null +++ b/lib/challenges/locales/ja/worlds/medium/pizza.json @@ -0,0 +1,50 @@ +{ + "id": "pizza", + "title": "ピザ", + "description": "おいしいピザをコードで作ろう!", + "startAt": 2, + "steps": [ + { + "hint": "筆の色をベージュ(`beige`)にしよう。", + "solution": "stroke beige" + }, + { + "hint": "筆の幅を50に。", + "solution": "stroke 50" + }, + { + "hint": "色を赤(`red`)にしよう。", + "solution": "color red" + }, + { + "hint": "半径200の円形を描こう。", + "solution": "circle 200" + }, + { + "hint": "美味しそう!筆の幅を0に戻そう。", + "solution": "stroke 0" + }, + { + "hint": "ソースに黄色で大きさ195の円形を描こう。", + "solution": "color yellow\ncircle 195", + "validate": [ + "color yellow", + "circle 195" + ] + }, + { + "hint": "そしてトッピング。色を暗赤色(`darkred`)にしよう。", + "solution": "color darkred" + }, + { + "hint": "そして`moveTo 164, 290`", + "solution": "moveTo 164, 290" + }, + { + "hint": "よっし、最後は半径20の円形を描こう。", + "solution": "circle 20" + } + ], + "completion_text": "美味しそう!想像を働かせて、他のトッピングを考えてみてから、ピザを友達と共有しよう。", + "cover": "pizza.png" +} diff --git a/lib/challenges/locales/ja/worlds/medium/planet.json b/lib/challenges/locales/ja/worlds/medium/planet.json new file mode 100644 index 000000000..4a4f343ca --- /dev/null +++ b/lib/challenges/locales/ja/worlds/medium/planet.json @@ -0,0 +1,60 @@ +{ + "id": "planet", + "title": "惑星画家", + "description": "自分だけの惑星をコードで描こう!", + "startAt": 2, + "steps": [ + { + "hint": "背景をヘキサのコードで設定しよう。`background '#444444'`を**タイプ**", + "solution": "background '#444444'", + "validate": "background '\\#444444'" + }, + { + "hint": "線を書かないように、筆の幅を0にしよう。", + "solution": "stroke 0" + }, + { + "hint": "色は黄色(`yellow`)にしよう。", + "solution": "color yellow" + }, + { + "hint": "次はループを始めよう。`for i in [ 0 .. 32 ]`を**タイプ**", + "solution": "for i in [ 0..32 ]" + }, + { + "hint": "そして、それぞれの星の位置を設定しよう。`moveTo (random 1, 500), (random 1, 500)`を**タイプ**", + "solution": " moveTo (random 1, 500), (random 1, 500)", + "validate": " moveTo ( *random +1,500 *),( *random +1,500 *)" + }, + { + "hint": "星は、半径5の丸で描こう。", + "solution": " circle 5" + }, + { + "hint": "次は、ループの外(インデントなし)で、色を紫にしよう。`color purple`を**タイプ**", + "solution": "color purple" + }, + { + "hint": "次は`moveTo 250, 250`", + "solution": "moveTo 250, 250" + }, + { + "hint": "半径170の円形を描こう。", + "solution": "circle 170" + }, + { + "hint": "色を白(`white`)に。", + "solution": "color white" + }, + { + "hint": "筆を太めで白に。`stroke white, 5`を**タイプ**", + "solution": "stroke white, 5" + }, + { + "hint": "最後に楕円形を描こう。`ellipse 220, 4`を**タイプ**", + "solution": "ellipse 220, 4" + } + ], + "completion_text": "いやー、まるで宇宙だ!共有する前に、色を変えて、惑星をもっと面白くしてみよう!", + "cover": "planet.png" +} diff --git a/lib/challenges/locales/ja/worlds/medium/random.json b/lib/challenges/locales/ja/worlds/medium/random.json new file mode 100644 index 000000000..bc2dd60e7 --- /dev/null +++ b/lib/challenges/locales/ja/worlds/medium/random.json @@ -0,0 +1,46 @@ +{ + "id": "random", + "title": "でたらめ", + "description": "物をどこに置けば良いか迷っていたら、そのための関数はあるよ!", + "startAt": 2, + "steps": [ + { + "hint": "カーソルを適当(不特定)な位置に動かそう。`moveTo (random 1, 500), (random 1, 500)`を**タイプ**", + "solution": "moveTo (random 1, 500), (random 1, 500)" + }, + { + "hint": "色を赤(red)にしよう。`color red`を**タイプ**", + "solution": "color red" + }, + { + "hint": "次は円形をこの適当な位置で描こう。`circle 200`を**タイプ**", + "solution": "circle 200" + }, + { + "hint": "色を緑(green)にしよう。", + "solution": "color green" + }, + { + "hint": "そして半径150の円形を描こう。", + "solution": "circle 150" + }, + { + "hint": "色を黄色(yellow)にしよう。", + "solution": "color yellow" + }, + { + "hint": "半径100の円形を描こう。", + "solution": "circle 100" + }, + { + "hint": "色を青(blue)にしよう。", + "solution": "color blue" + }, + { + "hint": "最後に半径50の円形を描こう。", + "solution": "circle 50" + } + ], + "completion_text": "randomで形をデタラメな場所で描けるんだ。面白いね。", + "cover": "random.png" +} diff --git a/lib/challenges/locales/ja/worlds/medium/shrinking.json b/lib/challenges/locales/ja/worlds/medium/shrinking.json new file mode 100644 index 000000000..e22bd1e26 --- /dev/null +++ b/lib/challenges/locales/ja/worlds/medium/shrinking.json @@ -0,0 +1,28 @@ +{ + "id": "shrinking", + "title": "縮む円形", + "description": "forループで無限に縮む円形!", + "code": "", + "startAt": 1, + "steps": [ + { + "hint": "鉛筆を設定しよう。`stroke gray, 3`を**タイプ**", + "solution": "stroke gray, 3" + }, + { + "hint": "透明な色を設定しよう。`color null`を**タイプ**", + "solution": "color null" + }, + { + "hint": "32個の円形を一気に描こう。`for i in [ 0 .. 32 ]`を**タイプ**", + "solution": "for i in [ 0..32 ]" + }, + { + "hint": "完璧、そしてforループの中で円形を描こう。`circle 10 * i`を**タイプ**", + "solution": " circle 10 * i", + "validate": " circle 10 *\\* *i" + } + ], + "completion_text": "素晴らしい!forループでコードを繰り返すことができるんだ(一つ一つタイプしなくて良い)!", + "cover": "shrinking.png" +} diff --git a/lib/challenges/locales/ja/worlds/medium/starry.json b/lib/challenges/locales/ja/worlds/medium/starry.json new file mode 100644 index 000000000..1e43bec4a --- /dev/null +++ b/lib/challenges/locales/ja/worlds/medium/starry.json @@ -0,0 +1,35 @@ +{ + "id": "starry", + "title": "星空", + "description": "random関数で自分だけの星空をコードで描こう!", + "startAt": 2, + "steps": [ + { + "hint": "背景を紺色(darkblue)にしよう。", + "solution": "background darkblue", + "validate": "^background darkblue$" + }, + { + "hint": "次は鉛筆の幅を0にしよう。", + "solution": "stroke 0" + }, + { + "hint": "そして鉛筆の色を黄色(yellow)に。", + "solution": "color yellow" + }, + { + "hint": "ループを始めよう。`for i in [ 0 .. 32 ]`を**タイプ**", + "solution": "for i in [ 0..32 ]" + }, + { + "hint": "それぞれの星の位置をランダムに設定しよう。`moveTo (random 1, 500), (random 1, 500)`を**タイプ**", + "solution": " moveTo (random 1, 500), (random 1, 500)" + }, + { + "hint": "最後に星をそれぞれ5ピクセルの円形で描こう。", + "solution": " circle 5" + } + ], + "completion_text": "素晴らしい!スペースキーを押して、星を見てみよう…", + "cover": "starry-sky.png" +} diff --git a/lib/challenges/locales/ja/worlds/mischiefweek2015/cat.json b/lib/challenges/locales/ja/worlds/mischiefweek2015/cat.json new file mode 100644 index 000000000..b7838444b --- /dev/null +++ b/lib/challenges/locales/ja/worlds/mischiefweek2015/cat.json @@ -0,0 +1,139 @@ +{ + "id": "cat", + "title": "Spooky Cat", + "cover": "mischiefweek2015/mw-002-cat.png", + "description": "Make a spooky cat with code", + "start_date": "2015-10-27T06:00:00", + "startAt": 2, + "completion_text": "Nice work - you made a spooky black cat! Try changing its color or even its tail! Don't forget to share your cat afterwards.", + "steps": [ + { + "hint": "We can make the background a spooky black by **typing** `background black`.", + "solution": "background black" + }, + { + "hint": "Set the stroke to zero so we have no outlines. **Type** `stroke 0`", + "solution": "stroke 0" + }, + { + "hint": "Now let's set the color of the full moon. **Type** `color lightgray`", + "solution": "color lightgray" + }, + { + "hint": "Create a nice big circle for the moon. **Type** `circle 230`.", + "solution": "circle 230" + }, + { + "hint": "Now move downwards so we can draw the grass on the ground. **Type** `moveTo 250, 500`.", + "solution": "moveTo 250, 500" + }, + { + "hint": "It's night time, so we'll make the grass a dark green. **Type** `color darkgreen`.", + "solution": "color darkgreen" + }, + { + "hint": "Draw the grassy hill with an ellipse so it's round. **Type** `ellipse 300, 100`", + "solution": "ellipse 300, 100" + }, + { + "hint": "Now set the color of the cat! To make it black, **type** `color black`.", + "solution": "color black" + }, + { + "hint": "Move the cursor to draw the cat in the middle! **Type** `moveTo 250, 250`.", + "solution": "moveTo 250, 250" + }, + { + "hint": "Let's draw the head with an ellipse. **Type** `ellipse 60, 40`.", + "solution": "ellipse 60, 40" + }, + { + "hint": "Let's move to right and up to draw the first ear. **Type** `moveTo 280, 220`.", + "solution": "moveTo 280, 220" + }, + { + "hint": "We'll use the polygon function to make a nice pointy ear! **Type** `polygon 0, -40, 28, 20, close`.", + "solution": "polygon 0, -40, 28, 20, close" + }, + { + "hint": "Move to the left by 60 so we can draw the other ear! **Type** `move -60`.", + "solution": "move -60" + }, + { + "hint": "This ear is a reflection of the other one! **Type** `polygon 0, -40, -28, 20, close`.", + "solution": "polygon 0, -40, -28, 20, close" + }, + { + "hint": "Let's make the neck underneath. **Type** `moveTo 250, 310`.", + "solution": "moveTo 250, 310" + }, + { + "hint": "Draw it using an ellipse! **Type** `ellipse 30, 50`.", + "solution": "ellipse 30, 50" + }, + { + "hint": "Now lets make the body below. **Type** `moveTo 250, 360`.", + "solution": "moveTo 250, 360" + }, + { + "hint": "We'll use a bigger ellipse this time round! **type** `ellipse 50, 60`.", + "solution": "ellipse 50, 60" + }, + { + "hint": "Now we need to move down and right to make the tail! **Type** `moveTo 320, 380`.", + "solution": "moveTo 320, 380" + }, + { + "hint": "Let's use a sneaky text trick to make a curvy tail. **Type** `font 150`.", + "solution": "font 150" + }, + { + "hint": "We'll make the text bold to make a large. **Type** `bold true`.", + "solution": "bold true" + }, + { + "hint": "Great! Now draw the tail by **typing** `text 'S'`.", + "solution": "text 'S'" + }, + { + "hint": "Finally, we'll make the eyes. **Type** `moveTo 225, 250`.", + "solution": "moveTo 225, 250" + }, + { + "hint": "Set the color to yellow. **Type** `color yellow`.", + "solution": "color yellow" + }, + { + "hint": "We'll draw it using an ellipse. **Type** `ellipse 14, 6`.", + "solution": "ellipse 14, 6" + }, + { + "hint": "Now for the pupil! Set the color to black. **Type** `color black`.", + "solution": "color black" + }, + { + "hint": "Make a circle of radius 6. **Type** `circle 6`.", + "solution": "circle 6" + }, + { + "hint": "Great! Now lets move right to do the other eye. **Type** `moveTo 275, 250`.", + "solution": "moveTo 275, 250" + }, + { + "hint": "Set the color back to yellow. **Type** `color yellow`.", + "solution": "color yellow" + }, + { + "hint": "Make the same ellipse as before. **Type** `ellipse 14,6`.", + "solution": "ellipse 14, 6" + }, + { + "hint": "Set the color back to black. **type** `color black`.", + "solution": "color black" + }, + { + "hint": "Lastly create the second pupil. **Type** `circle 6`.", + "solution": "circle 6" + } + ] +} diff --git a/lib/challenges/locales/ja/worlds/mischiefweek2015/ghost.json b/lib/challenges/locales/ja/worlds/mischiefweek2015/ghost.json new file mode 100644 index 000000000..456d04e4f --- /dev/null +++ b/lib/challenges/locales/ja/worlds/mischiefweek2015/ghost.json @@ -0,0 +1,136 @@ +{ + "id": "ghost", + "title": "Ghost", + "description": "Draw your very own ghost. Change the colors to win!", + "start_date": "2015-10-30T06:00:00", + "code": "ghostColor = '#809B79'\nfaceColor = '#634E42'\ntongueColor = '#7A5750'\n", + "startAt": 0, + "steps": [ + { + "hint": "We need to set up some variables to color the ghost - **Type** `ghostColor = '#809B79'`", + "solution": "ghostColor = '#809B79'" + }, + { + "hint": "Another variable for the face - **Type** `faceColor = '#634E42'`", + "solution": "faceColor = '#634E42'" + }, + { + "hint": "Finally a variable for the tongue - **Type** `tongueColor = '#7A5750'`", + "solution": "tongueColor = '#7A5750'" + }, + { + "hint": "We’ll use solid shapes, so set the stroke to zero with `stroke 0`", + "solution": "stroke 0" + }, + { + "hint": "Our ghost leaves a trail behind that we need to draw first, so we'll set the draw color to something slightly darker with `color darken(ghostColor, 10)`", + "solution": "color darken(ghostColor, 10)" + }, + { + "hint": "Move into position for the trail with `move 0, 60`", + "solution": "move 0, 60" + }, + { + "hint": "And then draw the trail with `circle 70`", + "solution": "circle 70" + }, + { + "hint": "Now we’ll draw the ghost’s body. Set the ghost’s color to our variable with `color ghostColor`", + "solution": "color ghostColor" + }, + { + "hint": "Now move back to draw the body, move back up to the center with `move 0, -60`", + "solution": "move 0, -60" + }, + { + "hint": "Draw the body with `circle 100`", + "solution": "circle 100" + }, + { + "hint": "Now we’ll draw the mouth with the faceColor variable we defined. **Type** `color faceColor`.", + "solution": "color faceColor" + }, + { + "hint": "Now move into position for the mouth with `move -40, 10`", + "solution": "move -40, 10" + }, + { + "hint": "Draw the mouth with `rectangle 80, 35`", + "solution": "rectangle 80, 35" + }, + { + "hint": "The teeth are a polygon. **Hint:** you can copy and paste this: `polygon 10, -10, 20, 0, 30, -10, 40, 0, 50, -10, 60, 0, 70, -10, 80, 0`", + "solution": "polygon 10, -10, 20, 0, 30, -10, 40, 0, 50, -10, 60, 0, 70, -10, 80, 0" + }, + { + "hint": "Now for the tongue, move to the bottom of the mouth with `move 40, 35`", + "solution": "move 40, 35" + }, + { + "hint": "Set the drawing color to our variable with `color tongueColor`", + "solution": "color tongueColor" + }, + { + "hint": "The tongue is a half-circle of radius 25, which we can draw with `arc 25, 0, 1`", + "solution": "arc 25, 0, 1" + }, + { + "hint": "For the eyes, set the drawing color with `color faceColor`", + "solution": "color faceColor" + }, + { + "hint": "Move into position for the eyes with `move -40, -80`", + "solution": "move -40, -80" + }, + { + "hint": "The eye is then drawn with `circle 10`", + "solution": "circle 10" + }, + { + "hint": "Move for the second eye with `move 80, 0`", + "solution": "move 80, 0" + }, + { + "hint": "Draw the second eye with `circle 10`", + "solution": "circle 10" + }, + { + "hint": "For our hands, were going to do something new: make a function. **Type** `hand = ->`", + "solution": "hand = ->" + }, + { + "hint": "This indented block is where your function goes. Any time you call this function this entire block of code will run. Lets set the stroke for our hand with `stroke 10, darken(ghostColor, 10)`", + "solution": " stroke 10, darken(ghostColor, 10)" + }, + { + "hint": "Then draw the first of the three fingers with `line 20, 30`", + "solution": " line 20, 30" + }, + { + "hint": "Then the second with `line 0, 35`", + "solution": " line 0, 35" + }, + { + "hint": "The final finger with `line -20, 30`", + "solution": " line -20, 30" + }, + { + "hint": "Now to draw the hands: make sure you are out of the function block by pressing **BACKSPACE**. Then **type** `move 60, 100` for the first hand.", + "solution": "move 60, 100" + }, + { + "hint": "Draw the hand at the current location with `hand()`", + "solution": "hand()" + }, + { + "hint": "Move over to the left to draw the other hand with `move -200, 0`", + "solution": "move -200, 0" + }, + { + "hint": "Draw the final hand with `hand()`", + "solution": "hand()" + } + ], + "completion_text": "Well done! You can change the color of your ghost by setting ghostColor, faceColor, and tongueColor to whatever you want.", + "cover": "mischiefweek2015/mw-005-ghost.png" +} diff --git a/lib/challenges/locales/ja/worlds/mischiefweek2015/hauntedhouse.json b/lib/challenges/locales/ja/worlds/mischiefweek2015/hauntedhouse.json new file mode 100644 index 000000000..cca16f838 --- /dev/null +++ b/lib/challenges/locales/ja/worlds/mischiefweek2015/hauntedhouse.json @@ -0,0 +1,11 @@ +{ + "id": "hauntedhouse", + "title": "Haunted House", + "description": "Dress the house up for Halloween and express your creativity.", + "start_date": "2015-11-01T06:00:00", + "completion_text": "It's Halloween Night! Change the colours at the top of the code to make this into a night scene then express your creativity by combining previous challenges with it or causing mischief, some ideas to get you started are in the comments.", + "startAt": 0, + "code": "#Colors, that need to be made spookier\nsky = aqua\nground = green\nsun = yellow\nbricks = brown\nroof = red\nframes = gray\nwindows = blue\ndoor = setBrightness(brown,-40)\n\n#Sky\nbackground sky\nstroke 0\nmoveTo 100, 100\ncolor sun\ncircle 60\n#Why not add some spooky clouds or bats\n\n#Ground\nmoveTo 250,530\ncolor ground\nellipse 500,150\n\n#House\nmoveTo 100,180\ncolor bricks\nrectangle 300,270\n\n#Windows\n#Cause some mischief, can you figure out how to throw eggs on all the windows in just 3 lines of code\ndrawWindow = (x,y) ->\n color setBrightness(frames,30)\n moveTo x,y\n rectangle 60,80\n color windows\n moveTo x+5,y+5\n rectangle 50,70\n color setBrightness(frames,30)\n moveTo x, y+37.5\n rectangle 60,5\n moveTo x+27.5, y\n rectangle 5,80\ndrawWindow(120,200)\ndrawWindow(220,200)\ndrawWindow(120,310)\ndrawWindow(320,200)\ndrawWindow(320,310)\n\n#Roof\ncolor roof\nmoveTo 100, 180\npolygon 150, -100, 300, 0\n#You could use the arc function to cover the roof in toilet paper \n\n\n#Door\ncolor setBrightness(frames,-10)\nmoveTo 215, 330\nrectangle 70,110\nmove 5,5\ncolor door\nrectangle 60,105\ncolor setBrightness(frames,-40) \nmove -15,105\nrectangle 90,20\nmove 65,-50\ncolor setBrightness(door,80)\ncircle 3\n#How about putting a pumpkin beside the door", + "steps": [], + "cover": "mischiefweek2015/mw-007-hauntedhouse.png" +} diff --git a/lib/challenges/locales/ja/worlds/mischiefweek2015/index.json b/lib/challenges/locales/ja/worlds/mischiefweek2015/index.json new file mode 100644 index 000000000..2bbe6689e --- /dev/null +++ b/lib/challenges/locales/ja/worlds/mischiefweek2015/index.json @@ -0,0 +1,11 @@ +{ + "challenges": [ + "./skull", + "./cat", + "./pumpkin", + "./potion", + "./ghost", + "./spiderweb", + "./hauntedhouse" + ] +} diff --git a/lib/challenges/locales/ja/worlds/mischiefweek2015/potion.json b/lib/challenges/locales/ja/worlds/mischiefweek2015/potion.json new file mode 100644 index 000000000..cfb784232 --- /dev/null +++ b/lib/challenges/locales/ja/worlds/mischiefweek2015/potion.json @@ -0,0 +1,96 @@ +{ + "id": "potion", + "title": "Potion Flask", + "description": "Brew a potion with code.", + "start_date": "2015-10-29T06:00:00", + "code": "", + "startAt": 2, + "completion_text": "Well done! You can change the color of your potion by setting potionColor to whatever you want. The clear glass you made with opacity(white, .4) will give it a cool effect, whatever color you choose.", + "cover": "mischiefweek2015/mw-004-potion.png", + "steps": [ + { + "hint": "We want solid shapes for this challenge, so **type** `stroke 0`", + "solution": "stroke 0" + }, + { + "hint": "For a dark look, lets set `background charcoal`", + "solution": "background charcoal" + }, + { + "hint": "If we want to change our potion color we can set it to a variable. To do that **type** `potionColor = purple`", + "solution": "potionColor = purple" + }, + { + "hint": "Let’s move into position with `move 0, 50`", + "solution": "move 0, 50" + }, + { + "hint": "And set the drawing color with `color potionColor`", + "solution": "color potionColor" + }, + { + "hint": "Finally, we can draw the potion with `circle 90`", + "solution": "circle 90" + }, + { + "hint": "Our potion is going to go up the neck of the flask, and we will use a line. Set up the line style with `stroke potionColor, 40`", + "solution": "stroke potionColor, 40" + }, + { + "hint": "And draw the line up from the middle with `line 0, -120`.", + "solution": "line 0, -120" + }, + { + "hint": "Set the stroke back to zero for the flask’s glass. **Type** `stroke 0`", + "solution": "stroke 0" + }, + { + "hint": "Let’s add in another circle to give our potion a natural look. Move to the right and up with `move 30, -30`.", + "solution": "move 30, -30" + }, + { + "hint": "Set the drawing color to a shade slightly darker than the potion color with `color darken(potionColor, 10)`", + "solution": "color darken(potionColor, 10)" + }, + { + "hint": "Finally, draw the circle with `circle 20`", + "solution": "circle 20" + }, + { + "hint": "Move back to the center with `move -30, 30`", + "solution": "move -30, 30" + }, + { + "hint": "Set the color for the glass flask with `color opacity(white, .4)`", + "solution": "color opacity(white, .4)" + }, + { + "hint": "Then draw the flask with an arc. **Type** `arc 100, 1.4, 1.6`", + "solution": "arc 100, 1.4, 1.6" + }, + { + "hint": "See how the arc draws almost a complete circle, but leaves a nice flat top for us? Our flask neck will meet it there, but first we need to draw a cork behind the glass. **Type** `move 0, -130`", + "solution": "move 0, -130" + }, + { + "hint": "Set the drawing color for the cork with `color tan`", + "solution": "color tan" + }, + { + "hint": "And draw the cork with `polygon 20, 0, 30, -40, -30, -40, -20, 0`", + "solution": "polygon 20, 0, 30, -40, -30, -40, -20, 0" + }, + { + "hint": "Now for the neck, lets choose the see-through white color for our stroke. **Type** `stroke 60, opacity(white, .4)`", + "solution": "stroke 60, opacity(white, .4)" + }, + { + "hint": "Move up just a little bit for the neck with `move 0, -25`", + "solution": "move 0, -25" + }, + { + "hint": "Finally, draw the neck with `line 0, 60`", + "solution": "line 0, 60" + } + ] +} diff --git a/lib/challenges/locales/ja/worlds/mischiefweek2015/pumpkin.json b/lib/challenges/locales/ja/worlds/mischiefweek2015/pumpkin.json new file mode 100644 index 000000000..16e88cd86 --- /dev/null +++ b/lib/challenges/locales/ja/worlds/mischiefweek2015/pumpkin.json @@ -0,0 +1,87 @@ +{ + "id": "pumpkin", + "title": "Kan-o-lantern", + "cover": "mischiefweek2015/mw-003-pumpkin.png", + "description": "It wouldn't be Halloween without pumpkins, learn how to carve a spooky pumpkin then get creative by changing the face.", + "start_date": "2015-10-28T06:00:00", + "completion_text": "That's a nice Kan-o-lantern! But it needs to be lit to be truly spooky, can you figure out how to light the pumpkin by changing some colors, you could also try carving a spookier looking face. Show off your creativity then share your creation.", + "startAt": 0, + "steps": [ + { + "hint": "Let’s set a spooky scene, make it night time - **type** `background charcoal`", + "solution": "background charcoal" + }, + { + "hint": "The most distinctive thing about pumpkins is their bright orange skin, to set your fill color - **type** `color orange`", + "solution": "color orange" + }, + { + "hint": "We're going to use strokes to build the bulbous shape of the pumpkin, use the darken function to build contrast against the skin - **type** `stroke darken(orange, 20), 30`", + "solution": "stroke darken(orange, 20), 30" + }, + { + "hint": "Build your pumpkin slice by slice using ellipses - **type** `ellipse 180, 140`", + "solution": "ellipse 180, 140" + }, + { + "hint": "Add another slice - **type** `ellipse 130, 140`", + "solution": "ellipse 130, 140" + }, + { + "hint": "It's starting to take shape, add the final slice the same way - **type** `ellipse 50, 140`", + "solution": "ellipse 50, 140" + }, + { + "hint": "Pumpkins are actually fruits, so we need to draw a green stem - **type** `color green`", + "solution": "color green" + }, + { + "hint": "Turn off the orange stroke - **type** `stroke 0`", + "solution": "stroke 0" + }, + { + "hint": "Move the cursor to the top of the pumpkin - **type** `move -20, -180`", + "solution": "move -20, -180" + }, + { + "hint": "Draw the chunky stem of the pumpkin - **type** `square 40`", + "solution": "square 40" + }, + { + "hint": "Now we have a fresh pumpkin, we can get to the fun part, carving your design - **type** `color black`", + "solution": "color black" + }, + { + "hint": "We're going to give them a face, move the cursor to where the eye will be - **type** `moveTo 190, 275`", + "solution": "moveTo 190, 275" + }, + { + "hint": "Cut a hole for the first eye - **type** `circle 15`", + "solution": "circle 15" + }, + { + "hint": "Move the cursor to where the second eye will be - **type** `moveTo 310, 275`", + "solution": "moveTo 310, 275" + }, + { + "hint": "Cut the second hole the same size as the first - **type** `circle 15`", + "solution": "circle 15" + }, + { + "hint": "Next we need to give them a mouth - **type** `moveTo 250, 320`", + "solution": "moveTo 250, 320" + }, + { + "hint": "We need to turn the fill colour off by setting it to null - **type** `color null`", + "solution": "color null" + }, + { + "hint": "We'll use a thick black stroke for the mouth - **type** `stroke 15, black`", + "solution": "stroke 15, black" + }, + { + "hint": "Finally we will use the arc command to give them a smile. - **type** `arc 40, 1, 2, true`", + "solution": "arc 40, 1, 2, true" + } + ] +} diff --git a/lib/challenges/locales/ja/worlds/mischiefweek2015/skull.json b/lib/challenges/locales/ja/worlds/mischiefweek2015/skull.json new file mode 100644 index 000000000..ba27a9392 --- /dev/null +++ b/lib/challenges/locales/ja/worlds/mischiefweek2015/skull.json @@ -0,0 +1,75 @@ +{ + "id": "skull", + "title": "Skull", + "cover": "mischiefweek2015/mw-001-skull.png", + "start_date": "2015-10-26T06:00:00", + "description": "", + "completion_text": "Amazing skull! You can dress it up with some background patterns or other facial accessories. When you are done, share your creation for a chance to win it on a t-shirt!", + "startAt": 0, + "steps": [ + { + "hint": "First we need to set the spooky scene, make it night time - **type** `background charcoal`", + "solution": "background charcoal" + }, + { + "hint": "We want to draw solid shapes with no stroke, so **type** `stroke 0`", + "solution": "stroke 0" + }, + { + "hint": "We can move into position for the skull with `moveTo 250, 200`", + "solution": "moveTo 250, 200" + }, + { + "hint": "Our skull should be white, so set the drawing color with `color white`", + "solution": "color white" + }, + { + "hint": "The skull is made with an ellipse—a kind of squashed circle. Make this with `ellipse 140, 120`", + "solution": "ellipse 140, 120" + }, + { + "hint": "It's starting to take shape, add the final slice the same way - **type** `move -60, 90`", + "solution": "move -60, 90" + }, + { + "hint": "The mouth of the skull is a square we will draw with `square 120`", + "solution": "square 120" + }, + { + "hint": "Lets move up and over for the eyes - **type** `move 10, -50`", + "solution": "move 10, -50" + }, + { + "hint": "Our skull’s empty eyes peer into your soul. Set their color to charcoal with `color charcoal`", + "solution": "color charcoal" + }, + { + "hint": "The eye is a circle. Draw it with `circle 40`", + "solution": "circle 40" + }, + { + "hint": "Move on over for the other eye. **Type** `move 100`", + "solution": "move 100" + }, + { + "hint": "Now draw the other eye with `circle 40`", + "solution": "circle 40" + }, + { + "hint": "Move on over for the nose with `move -50, 60`", + "solution": "move -50, 60" + }, + { + "hint": "Then draw the nose with `circle 10`", + "solution": "circle 10" + }, + { + "hint": "Finally, for the mouth move down by **typing** `move -40, 60`", + "solution": "move -40, 60" + }, + { + "hint": "Finally, you draw the mouth with `rectangle 80, 20`", + "solution": "rectangle 80, 20" + } + ] +} diff --git a/lib/challenges/locales/ja/worlds/mischiefweek2015/spiderweb.json b/lib/challenges/locales/ja/worlds/mischiefweek2015/spiderweb.json new file mode 100644 index 000000000..7d3befdb4 --- /dev/null +++ b/lib/challenges/locales/ja/worlds/mischiefweek2015/spiderweb.json @@ -0,0 +1,12 @@ +{ + "id": "spiderweb", + "title": "Spider Web", + "description": "Play around with a spider web!", + "completion_text": "Happy Halloween! Today’s challenge is for you to play around with the code here. Can you make a different-colored web? Or a bigger spider? Thanks to community member @NOPx90 who coded the spiderweb!", + "cover": "mischiefweek2015/mw-006-spiderweb.png", + "start_date": "2015-10-31T06:00:00", + "startAt": 0, + "code": "# PLAY WITH THESE\nradius = 370\nframes = 30\nbridges = 10\ndegrees = 360\nrotation = 0\n\nbodySize = 80\nlegSpread = 90\nlegLength = 100\neyeSize = 4\neyeSpacing = 12\n\n\n# This defines the spiderweb\nclass SpiderWeb\n constructor: (@x, @y, @radius, @frames, @bridges, @degrees, @rotation) ->\n @x = @x ? 250\n @y = @y ? 250\n @radius = @radius ? 250\n @frames = @frames ? 16\n @bridges = @bridges ? 20\n @degrees = @degrees ? 360\n @rotation = @rotation ? 0\n @frameAngle = @degrees / @frames\n @draw()\n drawFrame: () ->\n moveTo @x , @y\n for i in [ 0 .. @frames ]\n if i * @frameAngle != 360\n radians = (i * @frameAngle + @rotation)*(Math.PI / 180)\n x = Math.cos(radians)\n y = -Math.sin(radians)\n line (x*@radius) , (y*@radius)\n drawBridge: () ->\n r = @radius\n for web in [ 1 .. @bridges ]\n r /= 1.2\n for i in [ 0 ... @frames ]\n # Starting postition\n r1 = (i * @frameAngle + @rotation)*(Math.PI / 180)\n x1 = Math.cos(r1)\n y1 = -Math.sin(r1)\n \n # End position\n r2 = (i * @frameAngle + @frameAngle + @rotation)*(Math.PI / 180)\n x2 = Math.cos(r2)\n y2 = -Math.sin(r2)\n moveTo x1 * r + @x , y1 * r + @y\n lineTo x2 * r + @x , y2 * r + @y\n draw: ( ) ->\n this.drawFrame()\n this.drawBridge()\n\n# Here is the drawing\nbackground setSaturation(darkpurple,-25)\nstroke white\nweb = new SpiderWeb(250,250, radius, frames, bridges, degrees, rotation)\n# Spider Body\nstroke white, 10\nmoveTo 250, 0\nline 0, 200\nmove 0, 200\ncolor black\nstroke 0\nellipse bodySize * 0.8, bodySize\n# Spider Legs\nstroke black, 5\ncolor null\npairOfLegs = (flipHori,flipVert) ->\n spread = legSpread * flipHori\n length = legLength * flipVert\n polygon spread, length, spread * 0.7, length * 2\n polygon spread * 1.3, length * 0.4, spread * 1.7, length * 1.5\npairOfLegs(1,1)\npairOfLegs(-1,1)\npairOfLegs(1,-1)\npairOfLegs(-1,-1)\n\n#Spider Head\nstroke 0\ncolor black\nmove 0, bodySize\nellipse bodySize * 0.5, bodySize * 0.4\ncolor orangered\nmove eyeSpacing * -1.5, eyeSpacing / -2\nfor [1 .. 4]\n circle eyeSize\n move 0, eyeSpacing\n circle eyeSize\n move eyeSpacing, eyeSpacing * -1\n", + "steps": [ + ] +} diff --git a/lib/challenges/locales/ja/worlds/pixelhack/chest.json b/lib/challenges/locales/ja/worlds/pixelhack/chest.json new file mode 100644 index 000000000..60635a1ec --- /dev/null +++ b/lib/challenges/locales/ja/worlds/pixelhack/chest.json @@ -0,0 +1,104 @@ +{ + "id": "chest", + "title": "Loot Chest", + "description": "A mysterious chest found with your code", + "code": "", + "startAt": 2, + "steps": [ + { + "hint": "Role Playing Games (RPGs) became one of the most popular genres of games in the late 80s. One of the most common objects in these games is the loot chest, let's start by setting a moody scene with a background **type** `background darkslategray`", + "solution": "background darkslategray" + }, + { + "hint": "Next we're going to turn the stroke off **type** `stroke 0`", + "solution": "stroke 0" + }, + { + "hint": "Position the cursor to the top left corner of where the chest will be - **type** `move -150,-100`", + "solution": "move -150,-100" + }, + { + "hint": "Set the color to gold to give the impression of riches inside **type** `color gold`", + "solution": "color gold" + }, + { + "hint": "We're going to layer this up to keep the number of shapes we have to draw to a minimum, first we draw the golden frame draw a `rectangle` 300 by 200", + "solution": "rectangle 300,200" + }, + { + "hint": "Next we are going to add a highlight to the gold **type** `color lightyellow`", + "solution": "color lightyellow" + }, + { + "hint": "With 8-bit art, simple details add a lot to an object, add a 25 by 100 `rectangle` to give the gold a nice sheen", + "solution": "rectangle 25,100" + }, + { + "hint": "Move your cursor to get ready to draw the wooden part of the chest **type** `move 25,0`", + "solution": "move 25,0" + }, + { + "hint": "Change the fill color to `color brown`", + "solution": "color brown" + }, + { + "hint": "We use a trick of overlaying brown over the gold so the gold looks like a frame holding the wooden panels together **type** `rectangle 250,175`", + "solution": "rectangle 250,175" + }, + { + "hint": "Move the cursor into place to split the wooden part in half with a lid **type** `move 0,60`", + "solution": "move 0,60" + }, + { + "hint": "Switch your `color` back to gold", + "solution": "color gold" + }, + { + "hint": "Draw the seam with a `rectangle` 250 by 25", + "solution": "rectangle 250,25" + }, + { + "hint": "Next we'll continue our highlight effect **type** `color lightyellow`", + "solution": "color lightyellow" + }, + { + "hint": "Continue the highlight effect by drawing a `square` 25 big", + "solution": "square 25" + }, + { + "hint": "Finally we're going to finish with a clasp, move to the middle of the chest **type** `move 75,-25`", + "solution": "move 75,-25" + }, + { + "hint": "Set the `color` to gold so it matches the frame", + "solution": "color gold" + }, + { + "hint": "Draw a `rectangle` 100 by 75", + "solution": "rectangle 100,75" + }, + { + "hint": "Move in to draw the actual clasp **type** `move 25,25`", + "solution": "move 25,25" + }, + { + "hint": "Set the `color` to darkbrown", + "solution": "color darkbrown" + }, + { + "hint": "Finally draw a `rectangle` 50 by 75", + "solution": "rectangle 50,75" + } + ], + "completion_text": "That chest looks great, I wonder what loot is hiding within!", + "gallery": { + "cover_path": "/assets/challenges/images/pixelremixes/", + "remixes": [ + "chest-nether.png", + "chest-sunken.png", + "chest-open.png" + ] + }, + "cover": "pixel-chest.png", + "guide": "#### New Words\n**square** size | square 25\n\nThis is just a shorthand version of the rectangle \n\n#### What you'll make\n1. Role Playing Games (RPGs) became one of the most popular genres of games in the late 80s. One of the most common objects in these games is the loot chest, let's start by setting a moody scene with a background **type** `background darkslategray`\n2. Next we're going to turn the stroke off **type** `stroke 0`\n3. Position the cursor to the top left corner of where the chest will be **type** `move -150,-100`\n4. Set the color to gold to give the impression of riches inside **type** `color gold`\n5. We're going to layer this up to keep the number of shapes we have to draw to a minimum, first we draw the golden frame draw a `rectangle` 300 by 200\n6. Next we are going to add a highlight to the gold **type** `color lightyellow`\n7. With 8-bit art, simple details add a lot to an object, add a 25 by 100 `rectangle` to give the gold a nice sheen\n8. Move your cursor to get ready to draw the wooden part of the chest **type** `move 25,0`\n9. Change the fill color to `color brown`\n10. We use a trick of overlaying brown over the gold so the gold looks like a frame holding the wooden panels together **type** `rectangle 250,175`\n11. Move the cursor into place to split the wooden part in half with a lid **type** `move 0,60`\n12. Switch your `color` back to gold\n13. Draw the seam with a `rectangle` 250 by 25\n14. Next we'll continue our highlight effect **type** `color lightyellow`\n15. Continue the highlight effect by drawing a `square` 25 big\n16. Finally we're going to finish with a clasp, move to the middle of the chest **type** `move 75,-25`\n17. Set the `color` to gold so it matches the frame\n18. Draw a `rectangle` 100 by 75\n19. Move in to draw the actual clasp **type** `move 25,25`\n20. Set the `color` to darkbrown\n21. Finally draw a `rectangle` 50 by 75\n\n#### What you'll hack\nBy changing the colours and adding a few shapes you can build an environment around your chest. For a more complex challenge change your code to open the chest and code some loot within.\n\n#### Briefing \nThe loot chest has made appearances in too many video games to list. Possibly most prominently in games from the Legend of Zelda, where they would hold everything from small gifts of money to powerful new tools and weapons. What is in this loot chest? That’s up to you. When you’re done with the chest, open it up and put in your own creation as the loot.\n" +} diff --git a/lib/challenges/locales/ja/worlds/pixelhack/colorfrenzy.json b/lib/challenges/locales/ja/worlds/pixelhack/colorfrenzy.json new file mode 100644 index 000000000..ee72945ed --- /dev/null +++ b/lib/challenges/locales/ja/worlds/pixelhack/colorfrenzy.json @@ -0,0 +1,47 @@ +{ + "id": "colorfrenzy", + "title": "Color Frenzy", + "description": "Use a loop to draw an 8-bit pattern.", + "startAt": 2, + "steps": [ + { + "hint": "We’ll just use solid shapes with no stroke. So **type** `stroke 0`.", + "solution": "stroke 0" + }, + { + "hint": "For this one lets use two loops, one to go horizontally across the screen, and one to go down vertically. **Type** `for x in [ 0 .. 20 ]`", + "solution": "for x in [ 0 .. 20 ]" + }, + { + "hint": "The second loop should be `for y in [ 0 .. 20 ]`", + "solution": " for y in [ 0 .. 20 ]", + "validate": " for y in \\[ 0 .. 20 \\]" + }, + { + "hint": "Set the color with `color rotate red, x + y * 10`", + "solution": " color rotate red, x + y * 10", + "validate": " color rotate red, x \\+ y \\* 10" + }, + { + "hint": "Move into position with `moveTo x * 25, y * 25`", + "solution": " moveTo x * 25, y * 25", + "validate": " moveTo x \\* 25, y \\* 25" + }, + { + "hint": "Finally, lets add squares. **Type** `square 25`", + "solution": " square 25", + "validate": " square 25" + } + ], + "completion_text": "Well done! The rotate function cycles through colours creating a rainbow effect.", + "gallery": { + "cover_path": "/assets/challenges/images/pixelremixes/", + "remixes": [ + "color-quint.png", + "color-multi.png", + "color-random.png" + ] + }, + "cover": "pixel-colorfrenzy.png", + "guide": "#### What you'll make\n1. We’ll just use solid shapes with no stroke. So **type** `stroke 0`.\n2. For this one lets use two loops, one to go horizontally across the screen, and one to go down vertically. **Type** `for x in [ 0 .. 20 ]`\n3. The second loop should be `for y in [ 0 .. 20 ]`\n4. Set the color with `color rotate red, x * 10`\n5. Move into position with `moveTo x * 25, y * 25`\n6. Finally, lets add some randomness to the mix. **Type** `square random 20, 25`\n\n#### What you’ll hack\nBecause you are travelling across both the x and the y axes, you can have some pretty crazy color combinations. Using math you can make the rainbows repeat in interesting ways, and then change up how you draw on the screen using a random function. There are loads of variations, see what you can find!\n\n#### Briefing\nWe used one loop in the previous exercises to repeat actions, and then change one thing about the loop. In this challenge, we are going to be looping twice. The first loop is going to loop across the x coordinates—then the second loop is going to loop across the y coordinates. Because we have two loops, we are able to control color going in two different directions, and draw squares in two different directions. These “nested” loops will allow us to cover the canvas with color.\n" +} diff --git a/lib/challenges/locales/ja/worlds/pixelhack/diamondblock.json b/lib/challenges/locales/ja/worlds/pixelhack/diamondblock.json new file mode 100644 index 000000000..c2e73a762 --- /dev/null +++ b/lib/challenges/locales/ja/worlds/pixelhack/diamondblock.json @@ -0,0 +1,74 @@ +{ + "id": "diamondblock", + "title": "8-bit Diamond Block", + "description": "Make a diamond block with loops.", + "startAt": 2, + "steps": [ + { + "hint": "Set stroke to 0.", + "solution": "stroke 0" + }, + { + "hint": "We’ll use two loops for the stone. **Type** `for x in [0 ... 16]`", + "solution": "for x in [0 ... 16]" + }, + { + "hint": "For y use `for y in [0 ... 16]`", + "solution": " for y in [0 ... 16]" + }, + { + "hint": "We’ll use a randomly chosen shade of gray to make the stone. **Type** `color darken gray, random -6, 9`", + "solution": " color darken gray, random -6, 9", + "validate": " color darken gray, random -6, 9" + }, + { + "hint": "Move into position for each square with `moveTo x * 31.25, y * 31.25`", + "solution": " moveTo x * 31.25, y * 31.25", + "validate": " moveTo x \\* 31.25, y \\* 31.25" + }, + { + "hint": "Finally, draw the stone square with `square 32`", + "solution": " square 32", + "validate": " square 32" + }, + { + "hint": "Get out of the loop by bringing your cursor to the beginning of the line with **BACKSPACE**. We’ll start a new pair of loops to draw the diamond. **Type** `for x in [2 ... 14]`", + "solution": "for x in [2 ... 14]" + }, + { + "hint": "This time we are starting at 2 and ending at 14 because we only want the diamond to appear in the middle of the block. **Type** `for y in [2 ... 14]`", + "solution": " for y in [2 ... 14]" + }, + { + "hint": "The diamond should appear randomly, this if statement will only randomly draw the diamond. **Type** `if 1 == random 0, 4`", + "solution": " if 1 == random 0, 4", + "validate": " if 1 == random 0, 4" + }, + { + "hint": "Set the diamond color with `color lighten lightblue, random 0, 40`", + "solution": " color lighten lightblue, random 0, 40", + "validate": " color lighten lightblue, random 0, 40" + }, + { + "hint": "Move into position for each square with `moveTo x * 31.25, y * 31.25`", + "solution": " moveTo x * 31.25, y * 31.25", + "validate": " moveTo x \\* 31.25, y \\* 31.25" + }, + { + "hint": "Finally, draw the diamond square with `square 32`", + "solution": " square 32", + "validate": " square 32" + } + ], + "completion_text": "You’ve hacked the pixels and won! What’s next? More challenges and 8-bit art projects here at Kano if you are interested. Congratulations and well done!", + "gallery": { + "cover_path": "/assets/challenges/images/pixelremixes/", + "remixes": [ + "diamond-obsidian.png", + "diamond-rainbow.png", + "diamond-lotsof.png" + ] + }, + "cover": "pixel-diamondblock.png", + "guide": "#### What you'll make\n1. Set stroke to 0.\n2. We’ll use two loops for the stone. **Type** `for x in [0 ... 16]`\n3. For y use `for y in [0 ... 16]`\n4. We’ll use a randomly chosen shade of gray to make the stone. **Type** `color darken gray, random -6, 9`\n5. Move into position for each square with `moveTo x * 31.25, y * 31.25`\n6. Finally, draw the stone square with `square 32`\n7. Get out of the loop by bringing your cursor to the beginning of the line with **BACKSPACE**. We’ll start a new pair of loops to draw the diamond. **Type** `for x in [2 ... 14]`\n8. This time we are starting at 2 and ending at 14 because we only want the diamond to appear in the middle of the block. **Type** `for y in [2 ... 14]`\n9. The diamond should appear randomly, this if statement will only randomly draw the diamond. **Type** `if 1 == random 0, 4`\n10. Set the diamond color with `color lighten lightblue, random 0, 40`\n11. Move into position for each square with `moveTo x * 31.25, y * 31.25`\n12. Finally, draw the diamond square with `square 32`\n\n#### What you'll hack\nTo make this Minecraft Block your own all you need to change are two variables: the colour of the top and bottom parts. Make a strawberry, a water block, or anything else by just changing these two lines. For added complexity, make a Mycelium block with some randomness and another for loop. If you really want to have a challenge, try incorporating what you learned in the previous lesson and use the x and y values to add some extra color rotation to the dirt.\n\n#### Briefing\nThe grand finale: diamonds. This is the most precious and sought after Minecraft block. You’ll use nested for loops again to draw the stone, and then another pair of nested for loops to draw the stone, and then another nested for loop to draw the diamond. But as the diamond should be sprinkled throughout the stone we’ll use an if statement and use a random number to determine whether or not we should draw the square. Additionally, we only want to draw the diamond on the inside of the block, so our diamond-drawing loop will run from 2 to 14, rather than 0 to 16.\n" +} diff --git a/lib/challenges/locales/ja/worlds/pixelhack/forloop.json b/lib/challenges/locales/ja/worlds/pixelhack/forloop.json new file mode 100644 index 000000000..28798c88a --- /dev/null +++ b/lib/challenges/locales/ja/worlds/pixelhack/forloop.json @@ -0,0 +1,95 @@ +{ + "id": "forloop", + "title": "For Loop", + "description": "Use a for loop to build a snake with ease.", + "startAt": 2, + "steps": [ + { + "hint": "We're going to recreate the classic game Snake using the power of For Loops. First let's set a dirt background - **type** `background tan`", + "solution": "background tan" + }, + { + "hint": "Turn off the stroke **type** `stroke 0`", + "solution": "stroke 0" + }, + { + "hint": "First we position the head of the snake **type** `moveTo 80,250`", + "solution": "moveTo 80,250" + }, + { + "hint": "Set a snake-like color **type** `color olivedrab`", + "solution": "color olivedrab" + }, + { + "hint": "Draw a `circle` 30 pixels big for the head", + "solution": "circle 30" + }, + { + "hint": "This is where we will set the loop up, using the for function, the first number is where to start counting from and the second number is what to count to. So 1 .. 7 makes the computer count to 7 - **type** `for [1 .. 7]`", + "solution": "for [1 .. 7]" + }, + { + "hint": "Everything within this indent will be repeated 7 times, we need a move function to position each part of the body - **type** `move 50,0`", + "solution": " move 50,0" + }, + { + "hint": "We set the body color - **type** `color olivedrab`", + "solution": " color olivedrab" + }, + { + "hint": "Once we add a circle it'll be clear what is going on with the code being repeated several times - **type** `circle 30`", + "solution": " circle 30" + }, + { + "hint": "Let's add a square so the body looks more segmented, notice how we're now drawing 7 shapes for every line of code - **type** `square 30`", + "solution": " square 30" + }, + { + "hint": "We're going to add another detail to the tail so set the `color` to darkgreen", + "solution": " color darkgreen" + }, + { + "hint": "Draw another circle, the code is still indented this will be repeated 7 times - **type** `circle 20`", + "solution": " circle 20" + }, + { + "hint": "Finally draw a `square` 20 pixels big", + "solution": " square 20" + }, + { + "hint": "First make sure you are no longer in the for loop by hitting backspace so we're no longer indented. - **type** `moveTo 70,240`", + "solution": "moveTo 70,240" + }, + { + "hint": "Change the `color` to black", + "solution": "color black" + }, + { + "hint": "Draw an `ellipse` 10 pixels wide and 5 tall.", + "solution": "ellipse 10,5" + }, + { + "hint": "Finally we'll give it a tongue so it can hiss like a snake should - **type** `color salmon`", + "solution": "color salmon" + }, + { + "hint": "Position it on the face - **type** `move -15, 20`", + "solution": "move -15, 20" + }, + { + "hint": "We'll draw a rectangle with a negative width to stretch it out from the mouth - **type** `rectangle -20,4`", + "solution": "rectangle -20,4" + } + ], + "completion_text": "Now you have seen how we can create more art with less lines of code by using loops in clever ways, why not try changing the 7 in the for loop and see what happenes", + "gallery": { + "cover_path": "/assets/challenges/images/pixelremixes/", + "remixes": [ + "snake-tiny.png", + "snake-apple.png", + "snake-corner.png" + ] + }, + "cover": "pixel-forloop.png", + "guide": "#### New words\n**for i in [rangeMinimum ... rangeMax]**| for in [0 .. 10]\n\nThe for loop executes once for every number in the range provided. 10 times for the range [0 … 10] and 20 times for the range [0 … 20]. The loop executes any code that is indented four spaces appearing after it.\n\n#### What you'll make\n1. We're going to recreate the classic game Snake using the power of For Loops. First let's set a dirt background - **type** `background tan`\n2. Turn off the stroke **type** `stroke 0`\n3. First we position the head of the snake **type** `moveTo 80,250`\n4. Set a snake-like color **type** `color olivedrab`\n5. Draw a `circle` 30 pixels big for the head\n6. This is where we will set the loop up, using the for function, the first number is where to start counting from and the second number is what to count to. So 1 .. 7 makes the computer count to 7 - **type** `for [1 .. 7]`\n7. Everything within this indent will be repeated 7 times, we need a move function to position each part of the body - **type** `move 50,0`\n8. We set the body color - **type** `color olivedrab`\n9. Once we add a circle it'll be clear what is going on with the code being repeated several times - **type** `circle 30`\n10. Let's add a square so the body looks more segmented, notice how we're now drawing 7 shapes for every line of code - **type** `square 30`\n11. We're going to add another detail to the tail so set the `color` to darkgreen\n12. Draw another circle, the code is still indented this will be repeated 7 times - **type** `circle 20`\n13. Finally draw a `square` 20 pixels big\n14. First make sure you are no longer in the for loop by hitting backspace so we're no longer indented. - **type** `moveTo 70,240`\n15. Change the `color` to black\n16. Draw an `ellipse` 10 pixels wide and 5 tall.\n17. Finally we'll give it a tongue so it can hiss like a snake should - **type** `color salmon`\n18. Position it on the face - **type** `move -15, 20`\n19. We'll draw a rectangle with a negative width to stretch it out from the mouth - **type** `rectangle -20,4`\n\n#### What you’ll hack\nThe beauty of the loop is you can change your code once, and every single shape you draw will update. This is another reason to use loops, you can make big changes without rewriting big amounts of code.\n\n#### Briefing\nHow many times have you written the same commands over and over again in the last few challenges? For this snake challenge, each part of the snake is made up of the same circle shape. Instead of writing the same circle code over and over, you can have the computer do it for you!\n" +} diff --git a/lib/challenges/locales/ja/worlds/pixelhack/gradient.json b/lib/challenges/locales/ja/worlds/pixelhack/gradient.json new file mode 100644 index 000000000..acffb6a61 --- /dev/null +++ b/lib/challenges/locales/ja/worlds/pixelhack/gradient.json @@ -0,0 +1,56 @@ +{ + "id": "gradient", + "title": "8-bit sunset", + "description": "Use a loop to draw an 8-bit sunset.", + "startAt": 2, + "steps": [ + { + "hint": "We’ll just use solid shapes with no stroke. So **type** `stroke 0`.", + "solution": "stroke 0" + }, + { + "hint": "To better see the effect of our test, text to bold with `bold true`", + "solution": "bold true" + }, + { + "hint": "We’ll use a loop to draw the sunset. This time going from 0 to 10. **Type** `for y in [ 0 .. 10 ]`", + "solution": "for y in [ 0 .. 10 ]" + }, + { + "hint": "To understand how this loop works, we’ll draw the loop value out. Move into position with `moveTo 250, y * 50`", + "solution": " moveTo 250, y * 50", + "validate": " moveTo 250, y \\* 50" + }, + { + "hint": "Let’s inspect what our loop is doing. You can use the text function with plain text, but you can also pass it a variable. **Type** `text y` to see what the y values are across the screen.", + "solution": " text y", + "validate": " text y" + }, + { + "hint": "The y variable is increasing every time we go through the loop. It goes from 0 (which is off the screen) to 10. To draw our sunset we need to just move to the left edge. **Type** `moveTo 0, y * 50`", + "solution": " moveTo 0, y * 50", + "validate": " moveTo 0, y \\* 50" + }, + { + "hint": "We’ll use a special function to darken the color every loop. **Type** `color darken blue, y * 3`.", + "solution": " color darken blue, y * 3", + "validate": " color darken blue, y \\* 3" + }, + { + "hint": "Now for the sky, this will draw over your numbers. **Type** `rectangle 500, 50`.", + "solution": " rectangle 500, 50", + "validate": " rectangle 500, 50" + } + ], + "completion_text": "Beautiful! See how the blue gets darker as it goes down the screen. The y variable was being passed to the darken function. As the y value increased, the darken function made the blue color get darker.", + "gallery": { + "cover_path": "/assets/challenges/images/pixelremixes/", + "remixes": [ + "grad-yello.png", + "grad-sword.png", + "grad-mage.png" + ] + }, + "cover": "pixel-gradient.png", + "guide": "#### New words\n**bold** state | bold true\n\nCan set whether text is drawn as bold or regular. True is bold, false is regular.\n\n**text** string | text “hello world”\n\nDraws text centered on the drawing cursor. The properties of the text are controlled by the color, font, bold, and italic functions.\n\n\n#### What you'll make\n1. We’ll just use solid shapes with no stroke. So **type** `stroke 0`.\n2. To better see the effect of our test, text to bold with `bold true`\n3. We’ll use a loop to draw the sunset. This time going from 0 to 10. **Type** `for y in [ 0 .. 10 ]`\n4. To understand how this loop works, we’ll draw the loop value out. Move into position with `moveTo 250, y * 50`\n5. Let’s inspect what our loop is doing. You can use the text function with plain text, but you can also pass it a variable. **Type** `text y` to see what the y values are across the screen.\n6. The y variable is increasing every time we go through the loop. It goes from 0 (which is off the screen) to 10. To draw our sunset we need to just move to the left edge. **Type** `moveTo 0, y * 50`\n7. We’ll use a special function to darken the color every loop. **Type** `color darken blue, y * 3`.\n8. Now for the sky, this will draw over your numbers. **Type** `rectangle 500, 50`.\n\n\n#### What you’ll hack\nNow that you’ve got a few pixel art creations under your belt, why not bring them in here and give them the full background treatment they deserve!\n\n#### Briefing\nWith a loop you can tell a computer to do something over and over again. With the `for` loop, you can ask how many times the loop has happened, and depending on what loop it is vary what it is the loop is doing.\n\nIn this sunset, we want to draw rectangular blocks of the same size, and we want to move down a certain distance every time, but this time we need a way of telling the computer that they will have a different color every time. How do we do this? With variables. The way you can ask how many times the loop has happened in a `for` loop is with the word you start the loop with. When we say `for y in [ 0 .. 10]`, we are making the word `y` equal to how many times the loop has executed. It is incremented for us, so any time we use the variable `y`, it will tell the program how many times it has looped.\n\nBecause it increments by one every time, we can use it to travel across color shades by making a color darker in step as our y variable gets bigger. So at the beginning of the loop we have a small y and a regular color, and at the end we have a big y and a dark color.\n\n" +} diff --git a/lib/challenges/locales/ja/worlds/pixelhack/grassblock.json b/lib/challenges/locales/ja/worlds/pixelhack/grassblock.json new file mode 100644 index 000000000..e3ed59246 --- /dev/null +++ b/lib/challenges/locales/ja/worlds/pixelhack/grassblock.json @@ -0,0 +1,62 @@ +{ + "id": "grassblock", + "title": "8-bit Grass Block", + "description": "Make a block you can bring into Minecraft.", + "startAt": 1, + "steps": [ + { + "hint": "We’ll just use solid shapes with no stroke. So **type** `stroke 0`.", + "solution": "stroke 0" + }, + { + "hint": "We’ll have to use two loops here. **Type** `for x in [0 ... 16]`", + "solution": "for x in [0 ... 16]" + }, + { + "hint": "For y use `for y in [0 ... 16]`", + "solution": " for y in [0 ... 16]", + "validate": " for y in \\[0 ... 16\\]" + }, + { + "hint": "We’ll use a randomly chosen shade of brown to make the dirt. **Type** `color darken brown, random 0, 25`", + "solution": " color darken brown, random 0, 25", + "validate": " color darken brown, random 0, 25" + }, + { + "hint": "We’ll need to move into position for each square with `moveTo x * 31.25, y * 31.25`", + "solution": " moveTo x * 31.25, y * 31.25", + "validate": " moveTo x \\* 31.25, y \\* 31.25" + }, + { + "hint": "Finally, draw the dirt square with `square 32`", + "solution": " square 32", + "validate": " square 32" + }, + { + "hint": "The grass should only appear on the top of the block, so we’ll decide if the block should have a green bit drawn over it with `if 4 > y + random 0, 3`", + "solution": " if 4 > y + random 0, 3", + "validate": " if 4 > y \\+ random 0, 3" + }, + { + "hint": "Set the green color with the darken function. **Type** `color darken green, random 0, 25`", + "solution": " color darken green, random 0, 25", + "validate": " color darken green, random 0, 25" + }, + { + "hint": "Finally, draw the square with `square 32`", + "solution": " square 32", + "validate": " square 32" + } + ], + "completion_text": "Nice! Now you can change the brown and green colors to get an interesting effect. Can you make a block that looks like a strawberry?", + "gallery": { + "cover_path": "/assets/challenges/images/pixelremixes/", + "remixes": [ + "grass-overgrown.png", + "grass-strawb.png", + "grass-myce.png" + ] + }, + "cover": "pixel-grassblock.png", + "guide": "#### What you'll make\n1. We’ll just use solid shapes with no stroke. So **type** `stroke 0`.\n2. We’ll have to use two loops here. **Type** `for x in [0 ... 16]`\n3. For y use `for y in [0 ... 16]`\n4. We’ll use a randomly chosen shade of brown to make the dirt. **Type** `color darken brown, random 0, 25`\n5. We’ll need to move into position for each square with `moveTo x * 31.25, y * 31.25`\n6. Finally, draw the dirt square with `square 32`\n7. The grass should only appear on the top of the block, so we’ll decide if the block should have a green bit drawn over it with `if 4 > y + random 0, 3`\n8. Set the green color with the darken function. **Type** `color darken green, random 0, 25`\n9. Finally, draw the square with `square 32`\n\n#### What you’ll hack\nTo make this Minecraft Block your own all you need to change are two variables: the colour of the top and bottom parts. Make a strawberry, a water block, or anything else by just changing these two lines. For added complexity, make a Mycelium block with some randomness and another for loop. If you really want to have a challenge, try incorporating what you learned in the previous lesson and use the x and y values to add some extra color rotation to the dirt.\n\n#### Briefing \nOne of the most basic and commonly found blocks in minecraft is the grass block. Just sixteen blocks across and down, it is a very simple image, but we’re going to use randomness to give it a bit of texture. Two different layers will be used: one for the grass, and one for the dirt. \n\nIn each layer we will use the nested for loops to draw across and down the screen, and we’ll only change one thing about each: the color.\n" +} diff --git a/lib/challenges/locales/ja/worlds/pixelhack/index.json b/lib/challenges/locales/ja/worlds/pixelhack/index.json new file mode 100644 index 000000000..2552d1e17 --- /dev/null +++ b/lib/challenges/locales/ja/worlds/pixelhack/index.json @@ -0,0 +1,17 @@ +{ + "challenges": [ + "./pong", + "./ship", + "./tetris", + "./chest", + "./variables", + "./sword", + "./steve", + "./mage", + "./forloop", + "./gradient", + "./colorfrenzy", + "./grassblock", + "./diamondblock" + ] +} diff --git a/lib/challenges/locales/ja/worlds/pixelhack/mage.json b/lib/challenges/locales/ja/worlds/pixelhack/mage.json new file mode 100644 index 000000000..4486614f5 --- /dev/null +++ b/lib/challenges/locales/ja/worlds/pixelhack/mage.json @@ -0,0 +1,208 @@ +{ + "id": "mage", + "title": "RPG Mage", + "description": "Draw an 8-bit Aqua Mage", + "code": "", + "startAt": 2, + "steps": [ + { + "hint": "We're going to make a Mage character for an RPG game so first we need to set the scene, we'll use the darken function to change the color teal to a more suitable shade of dark blue - **type** `background darken teal,15 `", + "solution": "background darken teal,15" + }, + { + "hint": "We're making pixel art so we'll turn the stroke off - **type** `stroke 0`", + "solution": "stroke 0" + }, + { + "hint": "Let's set the color to saddlebrown for her hair - **type** `color saddlebrown`", + "solution": "color saddlebrown" + }, + { + "hint": "We'll use the moveTo function to move the cursor to a specific canvas coordinate - **type** `moveTo 120,80`", + "solution": "moveTo 120,80" + }, + { + "hint": "We're going to draw the hair first so we can layer the rest of the character over it to create depth - **type** `rectangle 320,400`", + "solution": "rectangle 320,400" + }, + { + "hint": "We're going to be drawing with blocks 20 by 20 pixels big - **type** `move 20,-20`", + "solution": "move 20,-20" + }, + { + "hint": "Stack up another layer of hair - **type** `rectangle 280,20`", + "solution": "rectangle 280,20" + }, + { + "hint": "Move upwards again to create a rounded effect - **type** `move 20,-20`", + "solution": "move 20,-20" + }, + { + "hint": "Draw the final row of hair in - **type** `rectangle 240,20`", + "solution": "rectangle 240,20" + }, + { + "hint": "Next we'll draw the face, - **type** `color sandybrown`", + "solution": "color sandybrown" + }, + { + "hint": "Move the cursor to the top corner of where the face will be - **type** `move 0,120`", + "solution": "move 0,120" + }, + { + "hint": "Draw the face with a `rectangle` that is 240 by 140", + "solution": "rectangle 240,140" + }, + { + "hint": "The face is a little too square so move the cursor up to the forehead - **type** `move 80,-40`", + "solution": "move 80,-40" + }, + { + "hint": "Draw another rectangle to create a fringe - **type** `rectangle 80,40`", + "solution": "rectangle 80,40" + }, + { + "hint": "Move the cursor down the face - **type** `move -40,180`", + "solution": "move -40,180" + }, + { + "hint": "Finish the face off by drawing a chin - **type** `rectangle 160,20`", + "solution": "rectangle 160,20" + }, + { + "hint": "Next we'll draw some robes, our mage specialises in water magic so we'll make them blue - **type** `color paleturquoise`", + "solution": "color paleturquoise" + }, + { + "hint": "Position the cursor for drawing the sleeves - **type** `move -100,20`", + "solution": "move -100,20" + }, + { + "hint": "Draw a `rectangle` 360 wide and 80 tall for the robe sleeves", + "solution": "rectangle 360,80" + }, + { + "hint": "Position the cursor to draw the body of the robe - **type** `move 60,80`", + "solution": "move 60,80" + }, + { + "hint": "Draw a `rectangle` 240 wide and 100 tall for the robe body", + "solution": "rectangle 240,100" + }, + { + "hint": "Next we'll draw a seam on the robe, change the `color` to teal", + "solution": "color teal" + }, + { + "hint": "Move the cursor to the middle of the robe - **type** `move 120,-80`", + "solution": "move 120,-80" + }, + { + "hint": "Draw a thin rectangle for the seam - **type** `rectangle 40,180`", + "solution": "rectangle 40,180" + }, + { + "hint": "Next up we'll draw the arms - **type** `move 140,40`", + "solution": "move 140,40" + }, + { + "hint": "Change the `color` back to sandybrown", + "solution": "color sandybrown" + }, + { + "hint": "Draw the arm with a `rectangle` 40 by 140", + "solution": "rectangle 40,140" + }, + { + "hint": "Move to the the other side of the body - **type** `move -380,40`", + "solution": "move -380,40" + }, + { + "hint": "This arm will be disconnected at first but don't worry, we haven't finished yet - **type** `rectangle 40,100`", + "solution": "rectangle 40,100" + }, + { + "hint": "Every mage needs a staff to cast magic, so we'll draw that next - **type** `color darkmagenta`", + "solution": "color darkmagenta" + }, + { + "hint": "Move to the top of the staff - **type** `move 60,-120`", + "solution": "move 60,-120" + }, + { + "hint": "Draw the staff over the arm so it looks like it's being held - **type** `rectangle -40,220`", + "solution": "rectangle -40,220" + }, + { + "hint": "As we said at the start our character uses water magic so set the color to aquamarine - **type** `color aquamarine`", + "solution": "color aquamarine" + }, + { + "hint": "Draw an orb at the top of the staff, if we use negative numbers then shapes are drawn backwards - **type** `square -80`", + "solution": "square -80" + }, + { + "hint": "We're also going to draw a magic circlet, move to the forehead - **type** `move 60,-200`", + "solution": "move 60,-200" + }, + { + "hint": "Draw a `rectangle` that is 240 by 20", + "solution": "rectangle 240,20" + }, + { + "hint": "Shift down a row on our grid - **type** `move -20,20`", + "solution": "move -20,20" + }, + { + "hint": "Finish off the circlet - **type** `rectangle 280,20`", + "solution": "rectangle 280,20" + }, + { + "hint": "We just need to finish off the face so position the cursor over the eyes - **type** `move 60,60`", + "solution": "move 60,60" + }, + { + "hint": "Set the `color` to black", + "solution": "color black" + }, + { + "hint": "Draw the eyes long and thin - **type** `rectangle 40,80`", + "solution": "rectangle 40,80" + }, + { + "hint": "Move across for the other eye - **type** `move 120,0`", + "solution": "move 120,0" + }, + { + "hint": "Draw the other eye - **type** `rectangle 40,80`", + "solution": "rectangle 40,80" + }, + { + "hint": "One last detail, we're going to make the eyes shiny - **type** `color white`", + "solution": "color white" + }, + { + "hint": "Draw a smaller rectangle within the pupil - **type** `rectangle 20,40`", + "solution": "rectangle 20,40" + }, + { + "hint": "Move to the other eye - **type** `move -120,0`", + "solution": "move -120,0" + }, + { + "hint": "Finish off with one last rectangle - **type** `rectangle 20,40`", + "solution": "rectangle 20,40" + } + ], + "completion_text": "Well done! Your mage is ready to raid some dungeons and cast some spells. Why not change the colours of the outfit to red for fire magic.", + "gallery": { + "cover_path": "/assets/challenges/images/pixelremixes/", + "remixes": [ + "mage-fire.png", + "mage-light.png", + "mage-warrior.png" + ] + }, + "cover": "pixel-mage.png", + "guide": "#### What you'll make\n1. We're going to make a Mage character for an RPG game so first we need to set the scene, we'll use the darken function to change the color teal to a more suitable shade of dark blue - **type** `background darken teal,15 `\n2. We're making pixel art so we'll turn the stroke off - **type** `stroke 0`\n3. Let's set the color to saddlebrown for her hair - **type** `color saddlebrown`\n4. We'll use the moveTo function to move the cursor to a specific canvas coordinate - **type** `moveTo 120,80`\n5. We're going to draw the hair first so we can layer the rest of the character over it to create depth - **type** `rectangle 320,400`\n6. We're going to be drawing with blocks 20 by 20 pixels big - **type** `move 20,-20`\n7. Stack up another layer of hair - **type** `rectangle 280,20`\n8. Move upwards again to create a rounded effect - **type** `move 20,-20`\n9. Draw the final row of hair in - **type** `rectangle 240,20`\n10. Next we'll draw the face, - **type** `color sandybrown`\n11. Move the cursor to the top corner of where the face will be - **type** `move 0,120`\n12. Draw the face with a `rectangle` that is 240 by 140\n13. The face is a little too square so move the cursor up to the forehead - **type** `move 80,-40`\n14. Draw another rectangle to create a fringe - **type** `rectangle 80,40`\n15. Move the cursor down the face - **type** `move -40,180`\n16. Finish the face off by drawing a chin - **type** `rectangle 160,20`\n17. Next we'll draw some robes, our mage specialises in water magic so we'll make them blue - **type** `color paleturquoise`\n18. Position the cursor for drawing the sleeves - **type** `move -100,20`\n19. Draw a `rectangle` 360 wide and 80 tall for the robe sleeves\n20. Position the cursor to draw the body of the robe - **type** `move 60,80`\n21. Draw a `rectangle` 240 wide and 100 tall for the robe body\n22. Next we'll draw a seam on the robe, change the `color` to teal\n23. Move the cursor to the middle of the robe - **type** `move 120,-80`\n24. Draw a thin rectangle for the seam - **type** `rectangle 40,180`\n25. Next up we'll draw the arms - **type** `move 140,40`\n26. Change the `color` back to sandybrown\n27. Draw the arm with a `rectangle` 40 by 140\n28. Move to the the other side of the body - **type** `move -380,40`\n29. This arm will be disconnected at first but don't worry, we haven't finished yet - **type** `rectangle 40,100`\n30. Every mage needs a staff to cast magic, so we'll draw that next - **type** `color darkmagenta`\n31. Move to the top of the staff - **type** `move 60,-120`\n32. Draw the staff over the arm so it looks like it's being held - **type** `rectangle -40,220`\n33. As we said at the start our character uses water magic so set the color to aquamarine - **type** `color aquamarine`\n34. Draw an orb at the top of the staff, if we use negative numbers then shapes are drawn backwards - **type** `square -80`\n35. We're also going to draw a magic circlet, move to the forehead - **type** `move 60,-200`\n36. Draw a `rectangle` that is 240 by 20\n37. Shift down a row on our grid - **type** `move -20,20`\n38. Finish off the circlet - **type** `rectangle 280,20`\n39. We just need to finish off the face so position the cursor over the eyes - **type** `move 60,60`\n40. Set the `color` to black\n41. Draw the eyes long and thin - **type** `rectangle 40,80`\n42. Move across for the other eye - **type** `move 120,0`\n43. Draw the other eye - **type** `rectangle 40,80`\n44. One last detail, we're going to make the eyes shiny - **type** `color white`\n45. Draw a smaller rectangle within the pupil - **type** `rectangle 20,40`\n46. Move to the other eye - **type** `move -120,0`\n47. Finish off with one last rectangle - **type** `rectangle 20,40`\n\n#### What you’ll hack\nThis is a much more intricate drawing, so there are many more things to change. You can go through the colours making up the image and change them to a new palette, and add in new objects. Take a look at the warrior and the lightning mage as ways of powering up your warrior with new powers, armour and weapons.\n\n#### Briefing\nThe simple shapes you have been putting together into simple designs can be refined and brought into more complex creations. This RPG Mage is a much more intricate design, but uses just the same tools to create them.\n" +} diff --git a/lib/challenges/locales/ja/worlds/pixelhack/pong.json b/lib/challenges/locales/ja/worlds/pixelhack/pong.json new file mode 100644 index 000000000..360721423 --- /dev/null +++ b/lib/challenges/locales/ja/worlds/pixelhack/pong.json @@ -0,0 +1,40 @@ +{ + "id": "pong", + "title": "ポン", + "description": "ポン試合をコードで描こう。", + "code": "", + "startAt": 2, + "steps": [ + { + "hint": "ポンは(1972年)最初の家庭用ゲームコンソールの一つだった。とても基本的な卓球ゲームなんだ。卓球をやるには何が必要だろう?そうだ、ボールだね。`circle 15`を**タイプ**", + "solution": "circle 15" + }, + { + "hint": "次はパドルが必要だ。moveTo関数を使って、物の位置を決められる。moveToの後の最初の数字は水平(左右)の位置を、2つ目の数字は垂直(上下)の位置を示している。`moveTo 30,100`を**タイプ**", + "solution": "moveTo 30,100" + }, + { + "hint": "パドルを長方形(`rectangle`)関数で描こう。`rectangle 20, 100`を**タイプ**", + "solution": "rectangle 20, 100" + }, + { + "hint": "一人でポンはつまらないから、相手が必要。`moveTo 450,300`を**タイプ**", + "solution": "moveTo 450,300" + }, + { + "hint": "最後は相手のパドルを描こう。最初の数字は幅で、2つ目の数は高さを示している。`rectangle 20, 100`を**タイプ**", + "solution": "rectangle 20, 100" + } + ], + "completion_text": "できた!昔のビデオゲームを再現できた。でもそのままだとちょっとつまらないね。moveToの後の100にクリックし、値を変えてパドルを動かしてみよう。", + "gallery": { + "cover_path": "/assets/challenges/images/pixelremixes/", + "remixes": [ + "pong-white.png", + "pong-movecolor.png", + "pong-movepaddles.png" + ] + }, + "cover": "pixel-pong.png", + "guide": "#### 新しい単語\n**circle** radius | circle 15\n\n現在位置で円形を描く。数字が大きければ大きいほど、円形も大きくなる。半径(radius)は円形の中心から、端までの距離だ。\n\n**moveTo** x, y | moveTo 30, 100\n\n現在位置を新しい(x, y)場所へ動かす。最初の値はxで、水平の位置を示している。2つ目の値はyで、垂直(上下)の位置を示している。\n\n**rectangle** width, height | rectangle 20, 100\n\n長方形を現在位置で描く。幅(width)と高さ(height)をそれぞれ設定することで長方形の大きさを指定できる。\n\n**color** name | color red\n\n鉛筆の色(color)を変更する。色を設定すると、全ての形や線や文字がこの色になる。色を透明にもできる:`color null`をタイプするだけ。\n\n**background** colorName | background white\n\n背景の色を変える。\n\n#### これから作るのは\n1. ポンは(1972年)最初の家庭用ゲームコンソールの一つだった。とても基本的な卓球ゲームなんだ。卓球をやるには何が必要だろう?そうだ、ボールだね。`circle 15`を**タイプ**\n2. 次はパドルが必要だ。moveTo関数を使って、物の位置を決められる。moveToの後の最初の数字は水平(左右)の位置を、2つ目の数字は垂直(上下)の位置を示している。`moveTo 30,100`を**タイプ**\n3. パドルを長方形(`rectangle`)関数で描こう。`rectangle 20, 100`を**タイプ**\n4. 一人でポンはつまらないから、相手が必要。`moveTo 450,300`を**タイプ**\n5. 最後は相手のパドルを描こう。最初の数字は幅で、2つ目の数は高さを示している。`rectangle 20, 100`を**タイプ**\n\n#### 追加チャレンジ\n美術家の重要なツールの一つは「色」である。最初の色は黒(black)で、形などを描く度に黒で描かれる。\n\n色を例えば赤(red)に変えることができる:最初の`moveTo`の後に`color red`を`rectangle 20, 100`の前にタイプすれば、パドルを違う色で描ける。ただし、色が変わるのはcolorの後だけなので、最後の行にcolorをタイプしても何も変わらない。\n\n背景の色をbackgroundで変えることができる。backgroundをどこに入れても大丈夫で、普通は一回だけ入れることになるが、一番上に入れることがお勧め。\n\n最後に、moveToの後の2つ目の数字を変えると、パドルを上下に動かすことができる。数字を簡単に変えるには、数字にクリックし、スライダーを動かせばいい。\n\n#### 概要\n1972年にアル・アルコーンさんはアタリ社入社後の新入社員課題として、ポンというゲームを作った。ボール一個とパドル2つで、非常にシンプルだったが、短期間で有名になった。そして何千万個も売れて、世界中で流行った。そこまで有名になったので、多くの競合他社は類似物も作り、アタリ社の成功を分けてもらおうとしていた。このゲームの成功のワケはシンプルでコピーしやすいことが一番だったと思われる。\n\nハッカーとして最初の仕事はポンゲームを作ることだ。ハッカーの秘密の一つは、リミックスだ:他人のコードとアイディアをパクり、組み合わせることだ。ポンのオリジナルアイディアを元に、自分だけのゲームが作れるんだ!まずスクリーンにボールとパドルを描く。そしてこれを元に新しい物を作ろう!\n" +} diff --git a/lib/challenges/locales/ja/worlds/pixelhack/ship.json b/lib/challenges/locales/ja/worlds/pixelhack/ship.json new file mode 100644 index 000000000..3e74d8152 --- /dev/null +++ b/lib/challenges/locales/ja/worlds/pixelhack/ship.json @@ -0,0 +1,68 @@ +{ + "id": "ship", + "title": "Asteroids Ship", + "description": "Code a vector spaceship using lines", + "code": "", + "startAt": 2, + "steps": [ + { + "hint": "Asteroids (1979) was one of the first major arcade games. It is set in space, so we're going to need to set the scene. **type** `background black`", + "solution": "background black" + }, + { + "hint": "The graphics in Asteroids were simple line based graphics called vectors, we still use a more complex version of this concept in computer graphics today. First we need to set our line color and width **type** `stroke white,5`", + "solution": "stroke white,5" + }, + { + "hint": "Next we use the move function to set the starting point for our first line. **type** `move 0, -70`", + "solution": "move 0, -70" + }, + { + "hint": "'Function' is the word we use to define what we are drawing. Let’s draw a line that starts where we just moved the cursor and ends at the bottom left. We type where we want the line to end after the function, so **type** `line -50,150` Try changing the Y value from 150 to -150 watch what happens. The line goes up, above where we started at -50. Let’s move it back down to 150!", + "solution": "line -50,150" + }, + { + "hint": "To move our cursor to the start of the next line we feed the previous coordinates into the move function. **type** `move -50,150`", + "solution": "move -50,150" + }, + { + "hint": "We draw a line inwards and upwards to form the thruster of the ship - **type** `line 50,-25`", + "solution": "line 50,-25" + }, + { + "hint": "Again moving to the same coordinates for a continuous line **type** `move 50,-25`", + "solution": "move 50,-25" + }, + { + "hint": "We replicate the shape for the right side of the ship by reversing the second coordinate to draw downwards instead of up **type** `line 50,25`", + "solution": "line 50,25" + }, + { + "hint": "Follow through with the line again **type** `move 50,25`", + "solution": "move 50,25" + }, + { + "hint": "Our ship starts to take shape. To make a line that goes from the end of the one we just drew to connect back up at the top **type** `line -50,-150`", + "solution": "line -50,-150" + }, + { + "hint": "Finally we move back to our starting point to add a final touch **type** `move -50,-150`", + "solution": "move -50,-150" + }, + { + "hint": "We draw a line down the centre to help the simple shape look more like a ship, early videogames had only a fraction of computing power we are used to today, so graphics had to be basic. **type** `line 0,125`", + "solution": "line 0,125" + } + ], + "completion_text": "It might not look like much but simple graphics like this were where videogames we know today began and games like this lay the foundations for the 3D graphics we're used to today.", + "gallery": { + "cover_path": "/assets/challenges/images/pixelremixes/", + "remixes": [ + "ship-golden.png", + "ship-thrust.png", + "ship-sleek.png" + ] + }, + "cover": "pixel-ship.png", + "guide": "#### New words\n**move** x, y | move 50, 25\n\nMoves the drawing cursor from the current position. The difference from moveTo is that this is relative, not absolute. `move 50, 25` will move the cursor 50 to the right, and 25 down from the current position, as opposed to from the top-left corner. The first value is the x value, which controls how far across horizontally the x part of the coordinate should go. The second value is the y coordinate, which controls how far down vertically the y coordinate should go. Negative values will send it in the opposite direction.\n\n**line** x, y | line 50, 25\n\nDraws a line from the current position to a relative position. The x, y coordinates control the point relative to the cursor where the line will be drawn to.\n\n**stroke** color, width | stroke white, 5\n\nSets the drawing stroke. All following shapes and text will be drawn with the stroke color and width set to this until you change it again. This function is smart and can accept arguments in any order, or only one at a time.\n\n#### What you'll make\n1. Asteroids (1979) was one of the first major arcade games. It was set in space so we're going to need to set the scene **type** `background black`\n2. The graphics in Asteroids were simple line based graphics called vectors, we still use a more complex version of this concept in computer graphics today. First we need to set our line color and width **type** `stroke white,5`\n3. Next we use the move function to set the starting point for our first line. **type** `move 0, -70`\n4. We use the line function to draw a line relative to our starting position, we use a negative number first to move to the left and a positive number second to move downward **type** `line -50,150`\n5. To move our cursor to the start of the next line we feed the previous coordinates into the move function. **type** `move -50,150`\n6. We draw a line inwards and upwards to form the thruster of the ship **type** `line 50,-25`\n7. Again moving to the same coordinates for a continuous line **type** `move 50,-25`\n8. We replicate the shape for the right side of the ship by reversing the second coordinate to draw downwards instead of up **type** `line 50,25`\n9. Follow through with the line again **type** `move 50,25`\n10. Our ship starts to take shape **type** `line -50,-150`\n11. Finally we move back to our starting point to add a final touch **type** `move -50,-150`\n12. We draw a line down the centre to help the simple shape look more like a ship, early videogames had only a fraction of computing power we are used to today, so graphics had to be basic. **type** `line 0,125`\n\n#### What you’ll hack\nIt might not look like much but graphics like this are where the videogames we know today began. Games like this lay the foundations for the 3D graphics we're used to today. You can turn your spaceship into a variety of different things by customising the stroke color and width. \n\nFor something more advanced, try drawing more lines.\n\n#### Briefing\nAsteroids (1979) was one of the first major arcade games. Limited by primitive drawing hardware, the game designers could only draw using simple line based graphics called vectors, we still use a more complex version of this concept in computer graphics today.\n" +} diff --git a/lib/challenges/locales/ja/worlds/pixelhack/steve.json b/lib/challenges/locales/ja/worlds/pixelhack/steve.json new file mode 100644 index 000000000..ed0339cc0 --- /dev/null +++ b/lib/challenges/locales/ja/worlds/pixelhack/steve.json @@ -0,0 +1,127 @@ +{ + "id": "steve", + "title": "Steve", + "description": "Make Steve's face with simple shapes.", + "startAt": 2, + "steps": [ + { + "hint": "We are going to just be using solid squares and rectangles, so lets turn our stroke off with `stroke 0`", + "solution": "stroke 0" + }, + { + "hint": "Set the background to lightbrown", + "solution": "background lightbrown" + }, + { + "hint": "Set the drawing color for the hair with `color brown`.", + "solution": "color brown" + }, + { + "hint": "The hair starts in the top-left corner, so **type** `moveTo 0, 0`.", + "solution": "moveTo 0, 0" + }, + { + "hint": "We’ll draw a rectangle, which takes a width and height parameter. **Type** `rectangle 500, 150`", + "solution": "rectangle 500, 150" + }, + { + "hint": "Set the drawing color to lightbrown**type** `color lightbrown`", + "solution": "color lightbrown" + }, + { + "hint": "Move into position for the forehead, **type** `moveTo 100, 100`", + "solution": "moveTo 100, 100" + }, + { + "hint": "Now to draw the forehead, **type** `rectangle 300, 50`", + "solution": "rectangle 300, 50" + }, + { + "hint": "For the eyes, set the color to white", + "solution": "color white" + }, + { + "hint": "Now let’s move with `moveTo 100, 200`", + "solution": "moveTo 100, 200" + }, + { + "hint": "Draw the eye with `square 50`", + "solution": "square 50" + }, + { + "hint": "For the other eye, **type** `moveTo 350, 200`", + "solution": "moveTo 350, 200" + }, + { + "hint": "And another square of size 50", + "solution": "square 50" + }, + { + "hint": "For the iris we’ll use the color purple.", + "solution": "color purple" + }, + { + "hint": "Move to `150, 200`.", + "solution": "moveTo 150, 200" + }, + { + "hint": "Draw a square of size 50.", + "solution": "square 50" + }, + { + "hint": "Move to `300, 200`.", + "solution": "moveTo 300, 200" + }, + { + "hint": "And draw the final iris with a square of size 50.", + "solution": "square 50" + }, + { + "hint": "We’ll draw the nose next. **Type** `color brown`", + "solution": "color brown" + }, + { + "hint": "Move into position with `moveTo 200, 250`.", + "solution": "moveTo 200, 250" + }, + { + "hint": "Draw out a rectangle of width `100` and height `50`.", + "solution": "rectangle 100, 50" + }, + { + "hint": "For the mouth set the drawing color to `saddlebrown`.", + "solution": "color saddlebrown" + }, + { + "hint": "Move to `150, 300`", + "solution": "moveTo 150, 300" + }, + { + "hint": "The mouth should be wide rectangle. **Type** `200, 100`.", + "solution": "rectangle 200, 100" + }, + { + "hint": "To make the mouth just right we need to cut out a bit of the top. Set the drawing color to the same color as the skin. **Type** `color lightbrown`", + "solution": "color lightbrown" + }, + { + "hint": "Move to `200, 300`.", + "solution": "moveTo 200, 300" + }, + { + "hint": "Finish up with `rectangle 100, 50` ", + "solution": "rectangle 100, 50" + } + ], + "completion_text": "Well done! Our character is looking good. What parts can you change to make the character look more like you?", + "gallery": { + "cover_path": "/assets/challenges/images/pixelremixes/", + "remixes": [ + "Steve-blue.png", + "Steve-beard.png", + "Steve-Alex.png" + ] + }, + "cover": "pixel-steve.png", + "guide": "#### What you'll make\n1. We are going to just be using solid squares and rectangles, so lets turn our stroke off with `stroke 0`\n2. Set the background to lightbrown\n3. Set the drawing color for the hair with `color brown`.\n4. The hair starts in the top-left corner, so **type** `moveTo 0, 0`.\n5. We’ll draw a rectangle, which takes a width and height parameter. **Type** `rectangle 500, 150`\n6. Set the drawing color to lightbrown**type** `color lightbrown`\n7. Move into position for the forehead, **type** `moveTo 100, 100`\n8. Now to draw the forehead, **type** `rectangle 300, 50`\n9. For the eyes, set the color to white\n10. Now let’s move with `moveTo 100, 200`\n11. Draw the eye with `square 50`\n12. For the other eye, **type** `moveTo 350, 200`\n13. And another square of size 50\n14. For the iris we’ll use the color purple.\n15. Move to `150, 200`.\n16. Draw a square of size 50.\n17. Move to `300, 200`.\n18. And draw the final iris with a square of size 50.\n19. We’ll draw the nose next. **Type** `color brown`\n20. Move into position with `moveTo 200, 250`.\n21. Draw out a rectangle of width `100` and height `50`.\n22. For the mouth set the drawing color to `saddlebrown`.\n23. Move to `150, 300`\n24. The mouth should be wide rectangle. **Type** `200, 100`.\n25. To make the mouth just right we need to cut out a bit of the top. Set the drawing color to the same color as the skin. **Type** `color lightbrown`\n26. Move to `200, 300`.\n27. Finish up with `rectangle 100, 50` \n\n#### What you’ll hack\nThe shapes here are simple, but that is what makes it so easy to remix and hack! Change the colors of the skin, eyes, or hair, or add in your own facial features to win!\n\n#### Briefing\nSteve is the hero of Minecraft. Not very much is known about Steve: who he is, where he came from, and whether he is even human. But he is the face of the most sensational game and building system of the decade. This simple composition with just squares and rectangles is brought to life with beautiful colors.\n" +} diff --git a/lib/challenges/locales/ja/worlds/pixelhack/sword.json b/lib/challenges/locales/ja/worlds/pixelhack/sword.json new file mode 100644 index 000000000..bc5491c80 --- /dev/null +++ b/lib/challenges/locales/ja/worlds/pixelhack/sword.json @@ -0,0 +1,96 @@ +{ + "id": "sword", + "title": "Diamond Sword", + "description": "Code a sword forged from pure diamonds", + "code": "", + "startAt": 2, + "steps": [ + { + "hint": "We're going to make a sword out of diamond so first we will set up some variables to represent the colors **type** `sword = aquamarine`", + "solution": "sword = aquamarine" + }, + { + "hint": "We set up enough variable to represent the darker areas of the sword, we can use the darken function to alter the color of our existing sword color. **type** `darksword = darken sword,40`", + "solution": "darksword = darken sword,40" + }, + { + "hint": "We start by setting the `background` color to slategray", + "solution": "background slategray" + }, + { + "hint": "Next we set our fill color to the variable we set up before **type** `color sword`", + "solution": "color sword" + }, + { + "hint": "and set our stroke color to the darker version of our sword color **type** `stroke darksword,20`", + "solution": "stroke darksword,20" + }, + { + "hint": "Move the cursor to where the top of the blade will be **type** `move -20,-180`", + "solution": "move -20,-180" + }, + { + "hint": "Draw the blade of the sword **type** `rectangle 40,230`", + "solution": "rectangle 40,230" + }, + { + "hint": "It's already starting to take shape, let's create the handle **type** `move 10,250`", + "solution": "move 10,250" + }, + { + "hint": "The grip isn't going to be made of diamond so set the `stroke` color to darkbrown", + "solution": "stroke darkbrown" + }, + { + "hint": "and the `color` to brown", + "solution": "color brown" + }, + { + "hint": "Draw a `rectangle` 20 by 100 for the grip", + "solution": "rectangle 20,100" + }, + { + "hint": "We're going to create the crossguard next **type** `move -70,-10`", + "solution": "move -70,-10" + }, + { + "hint": "Change the `stroke` color back to our darksword variable", + "solution": "stroke darksword" + }, + { + "hint": "We're going to use another color function: lighten to slightly change our diamond color **type** `color lighten darksword,10`", + "solution": "color lighten darksword,10" + }, + { + "hint": "Next draw a `rectangle` 160 by 20", + "solution": "rectangle 160,20" + }, + { + "hint": "Notice how the lighten function altered the diamond color. **type** `move 80, -240`", + "solution": "move 80, -240" + }, + { + "hint": "Finally we're going to add a highlight detail to finish the sword **type** `color white`", + "solution": "color white" + }, + { + "hint": "Turn the stroke off **type** `stroke 0`", + "solution": "stroke 0" + }, + { + "hint": "Draw a `rectangle` 10 by 230", + "solution": "rectangle 10, 230" + } + ], + "completion_text": "That sword looks exquisite, perfect for fighting your way out of some caves. Try changing the color on the first line, see how it changes all the other colors on the blade because of the variables.", + "gallery": { + "cover_path": "/assets/challenges/images/pixelremixes/", + "remixes": [ + "sword-golden.png", + "sword-shovel.png", + "sword-pickaxe.png" + ] + }, + "cover": "pixel-sword.png", + "guide": "#### New words\n**darken**(color, amount) | darken(blue, 40)\n\nReturns a lightened color by the amount you give it. The amount can be between 0 and 100.\n\n**lighten**(color, amount) | lighten(blue, 40)\n\nReturns a lightened color by the amount you give it. The amount can be between 0 and 100.\n\n\n#### What you'll make\n1. We're going to make a sword out of diamond so first we will set up some variables to represent the colors **type** `sword = aquamarine`\n2. We set up enough variable to represent the darker areas of the sword, we can use the darken function to alter the color of our existing sword color. **type** `darksword = darken sword,40`\n3. We start by setting the `background` color to slategray\n4. Next we set our fill color to the variable we set up before **type** `color sword`\n5. and set our stroke color to the darker version of our sword color **type** `stroke darksword,20`\n6. Move the cursor to where the top of the blade will be **type** `move -20,-180`\n7. Draw the blade of the sword **type** `rectangle 40,230`\n8. It's already starting to take shape, let's create the handle **type** `move 10,250`\n9. The grip isn't going to be made of diamond so set the `stroke` color to darkbrown\n10. and the `color` to brown\n11. Draw a `rectangle` 20 by 100 for the grip\n12. We're going to create the crossguard next **type** `move -70,-10`\n13. Change the `stroke` color back to our darksword variable\n14. We're going to use another color function: lighten to slightly change our diamond color **type** `color lighten darksword,10`\n15. Next draw a `rectangle` 160 by 20\n16. Notice how the lighten function altered the diamond color. **type** `move 80, -240`\n17. Finally we're going to add a highlight detail to finish the sword **type** `color white`\n18. Turn the stroke off **type** `stroke 0`\n19. Draw a `rectangle` 10 by 230\n\n#### What you’ll hack\nBecause all of the colors we used are just shades of our sword color, by changing one variable all the darker and lighter shades will change as well! We can make a diamond sword into a gold one by just changing the sword color.\n\nUsing the same code and style, what other Minecraft-inspired creations can you make?\n\n#### Briefing\nThe diamond sword is the most powerful weapon in the Minecraft players toolbelt. It is also the most difficult to make given the rarity of diamond. All of the different types of swords in Minecraft (diamond, gold, steel, stone…) follow a simple pattern in their design. The only thing that separates them visually is their color. For the diamond sword we’ll make a word called \"sword\" which is set to the color \"aquamarine\". To select different shades for the hilt and outlines, we’ll use the color with special color functions." +} diff --git a/lib/challenges/locales/ja/worlds/pixelhack/tetris.json b/lib/challenges/locales/ja/worlds/pixelhack/tetris.json new file mode 100644 index 000000000..bb9cfbc9f --- /dev/null +++ b/lib/challenges/locales/ja/worlds/pixelhack/tetris.json @@ -0,0 +1,96 @@ +{ + "id": "tetris", + "title": "Tetris", + "description": "Stack some Tetris blocks with code", + "code": "", + "startAt": 2, + "steps": [ + { + "hint": "Tetris (1984) was the first videogame to be exported from the USSR to the US, going on to sell 170 million copies. We're going to make some Tetris blocks, first turn the stroke off **type** `stroke 0`", + "solution": "stroke 0" + }, + { + "hint": "Next move your cursor to the start of the first block **type** `moveTo 150,200`", + "solution": "moveTo 150,200" + }, + { + "hint": "We're going to need some colors to tell the blocks apart, change the fill color of your shapes with the color function **type** `color crimson`", + "solution": "color crimson" + }, + { + "hint": "First we're going to draw an L shaped block **type** `rectangle 50,150`", + "solution": "rectangle 50,150" + }, + { + "hint": "Our blocks are all going to be to a 50x50 grid, so you'll notice all our draw and move commands are multiples of 50 **type** `move 0,100`", + "solution": "move 0,100" + }, + { + "hint": "Finish off the block with a 100,50 `rectangle`", + "solution": "rectangle 100,50" + }, + { + "hint": "Let's move to start the next block **type** `move 50,-100`", + "solution": "move 50,-100" + }, + { + "hint": "We'll change the color to tell them apart, color functions affect all shapes drawn below them in the code **type** `color seagreen`", + "solution": "color seagreen" + }, + { + "hint": "Next we'll be drawing the S shaped block **type** `rectangle 50,100`", + "solution": "rectangle 50,100" + }, + { + "hint": "Move one gridspace across and one down **type** `move 50,50`", + "solution": "move 50,50" + }, + { + "hint": "To make an S shape we create another `rectangle` of 50 by 100", + "solution": "rectangle 50,100" + }, + { + "hint": "On to the next block **type** `move 50,-100`", + "solution": "move 50,-100" + }, + { + "hint": "We change the color again **type** `color indigo`", + "solution": "color indigo" + }, + { + "hint": "Next we will draw a long and thin block, draw a `rectangle` 50 by 200", + "solution": "rectangle 50,200" + }, + { + "hint": "One final block to complete the square **type** `move -150,0`", + "solution": "move -150,0" + }, + { + "hint": "Let's make the `color` gold to stand out", + "solution": "color gold" + }, + { + "hint": "Another L block will fit nicely so draw the stem with **type** `rectangle 150,50`", + "solution": "rectangle 150,50" + }, + { + "hint": "Move into place to draw the foot **type** `move 100,0`", + "solution": "move 100,0" + }, + { + "hint": "Finally fill in the foot **type** `rectangle 50,100`", + "solution": "rectangle 50,100" + } + ], + "completion_text": "Well done you created a nice stack of tetrominoes, why not try changing the color of some of the blocks or drawing a few more to fill the screen.", + "gallery": { + "cover_path": "/assets/challenges/images/pixelremixes/", + "remixes": [ + "tetris-gameboy.png", + "tetris-3D.png", + "tetris-row.png" + ] + }, + "cover": "pixel-tetris.png", + "guide": "#### New words\n**color** name | color red\n\nChanges the drawing color. All following shapes and text will be drawn with the fill color set to this color until you change it again. To set the drawing color to transparent, type `color null`\n\n#### What you'll make\n1. Tetris (1984) was the first videogame to be exported from the USSR to the US, going on to sell 170 million copies. We're going to make some Tetris blocks, first turn the stroke off **type** `stroke 0`\n2. Next move your cursor to the start of the first block **type** `moveTo 150,200`\n3. We're going to need some colors to tell the blocks apart, change the fill color of your shapes with the color function **type** `color crimson`\n4. First we're going to draw an L shaped block **type** `rectangle 50,150`\n5. Our blocks are all going to be to a 50x50 grid, so you'll notice all our draw and move commands are multiples of 50 **type** `move 0,100`\n6. Finish off the block with a 100,50 `rectangle`\n7. Let's move to start the next block **type** `move 50,-100`\n8. We'll change the color to tell them apart, color functions affect all shapes drawn below them in the code **type** `color seagreen`\n9. Next we'll be drawing the S shaped block **type** `rectangle 50,100`\n10. Move one gridspace across and one down **type** `move 50,50`\n11. To make an S shape we create another `rectangle` of 50 by 100\n12. On to the next block **type** `move 50,-100`\n13. We change the color again **type** `color indigo`\n14. Next we will draw a long and thin block, draw a `rectangle` 50 by 200\n15. One final block to complete the square **type** `move -150,0`\n16. Let's make the `color` gold to stand out\n17. Another L block will fit nicely so draw the stem with **type** `rectangle 150,50`\n18. Move into place to draw the foot **type** `move 100,0`\n19. Finally fill in the foot **type** `rectangle 50,100`\n\n#### What you’ll hack\nNow you’ve made a cube, give each tetrimino whatever color you want, and add in more.\n\n#### Briefing \nTetris (1984) was the first videogame to be exported from the USSR to the US, going on to sell 170 million copies. We're going to make some Tetris blocks, which are known as tetriminos. Each tetrimino is made up of four squares that connect together, and fit together in interesting ways. In the game, tetriminos fall down endlessly and the goal is to make as many of them fit together without empty spaces.\n" +} diff --git a/lib/challenges/locales/ja/worlds/pixelhack/variables.json b/lib/challenges/locales/ja/worlds/pixelhack/variables.json new file mode 100644 index 000000000..e0972ff3d --- /dev/null +++ b/lib/challenges/locales/ja/worlds/pixelhack/variables.json @@ -0,0 +1,93 @@ +{ + "id": "variables", + "title": "Variables", + "description": "Use variables to create a maze dwelling ghost", + "code": "", + "startAt": 2, + "steps": [ + { + "hint": "This classic ghost character first appeared in Pac-Man (1980), because it's a ghost we're going to need a spooky background **type** `background navy`", + "solution": "background navy" + }, + { + "hint": "Next turn the stroke off by typing `stroke 0`", + "solution": "stroke 0" + }, + { + "hint": "Set the `color` to red", + "solution": "color red" + }, + { + "hint": "Here we're introducing something new, we're going to set the size of the ghost using a variable, variables are a way of repeating the same value in your code **type** `ghostsize = 100`", + "solution": "ghostsize = 100" + }, + { + "hint": "Move the cursor up to where the ghosts head will start **type** `move 0,-50`", + "solution": "move 0,-50" + }, + { + "hint": "We're going to use that variable we set earlier to draw the head, because we set the variable to 100 this command will create a circle 100 pixels big **type** `circle ghostsize`", + "solution": "circle ghostsize" + }, + { + "hint": "We're going to use the variable again, this time with the move command, by placing a minus symbol in front of it this command becomes the same as moving -100,0 **type** `move -ghostsize,0`", + "solution": "move -ghostsize,0" + }, + { + "hint": "Time to draw the rest of the ghost's body, because the body is relative to the head size we will use the variable again **type** `square ghostsize * 2`", + "solution": "square ghostsize * 2", + "validate": "square ghostsize \\* 2" + }, + { + "hint": "We're going to give it some eyes so we need to use the variable again to make sure they're positioned correctly on the head **type** `move ghostsize / 2`", + "solution": "move ghostsize / 2" + }, + { + "hint": "Set the `color` to white", + "solution": "color white" + }, + { + "hint": "Start the eyes off with a `circle` 20 pixels big", + "solution": "circle 20" + }, + { + "hint": "Now set the iris color **type** `color blue`", + "solution": "color blue" + }, + { + "hint": "Finally draw the iris **type** `circle 10`", + "solution": "circle 10" + }, + { + "hint": "We're gonna use the variable one last time to position the other eye correctly **type** `move ghostsize,0`", + "solution": "move ghostsize,0" + }, + { + "hint": "Repeat the process for the second eye, set the `color` to white", + "solution": "color white" + }, + { + "hint": "Draw a `circle` 20 pixels big", + "solution": "circle 20" + }, + { + "hint": "Set the `color` to blue", + "solution": "color blue" + }, + { + "hint": "Finally draw a `circle` 10 pixels big", + "solution": "circle 10" + } + ], + "completion_text": "Nice! Now because you have used a variable, you can click on the ghostsize number and use the slider to change the value. Notice how the eyes stay the same size because they are hardcoded numbers and everything else scales together.", + "gallery": { + "cover_path": "/assets/challenges/images/pixelremixes/", + "remixes": [ + "ghost-big.png", + "ghost-tired.png", + "ghost-scared.png" + ] + }, + "cover": "pixel-variables.png", + "guide": "#### New words\n**variable** = value | ghostsize = 100\n\nCreates a word that is assigned a value and can be used elsewhere.\n\n#### What you'll make\n1. This classic ghost character first appeared in Pac-Man (1980), because it's a ghost we're going to need a spooky background **type** `background navy`\n2. Next turn the stroke off by typing `stroke 0`\n3. Set the `color` to red\n4. Here we're introducing something new, we're going to set the size of the ghost using a variable, variables are a way of repeating the same value in your code **type** `ghostsize = 100`\n5. Move the cursor up to where the ghosts head will start **type** `move 0,-50`\n6. We're going to use that variable we set earlier to draw the head, because we set the variable to 100 this command will create a circle 100 pixels big **type** `circle ghostsize`\n7. We're going to use the variable again, this time with the move command, by placing a minus symbol in front of it this command becomes the same as moving -100,0 **type** `move -ghostsize,0`\n8. Time to draw the rest of the ghost's body, because the body is relative to the head size we will use the variable again **type** `square ghostsize * 2`\n9. We're going to give it some eyes so we need to use the variable again to make sure they're positioned correctly on the head **type** `move ghostsize / 2`\n10. Set the `color` to white\n11. Start the eyes off with a `circle` 20 pixels big\n12. Now set the iris color **type** `color blue`\n13. Finally draw the iris **type** `circle 10`\n14. We're gonna use the variable one last time to position the other eye correctly **type** `move ghostsize,0`\n15. Repeat the process for the second eye, set the `color` to white\n16. Draw a `circle` 20 pixels big\n17. Set the `color` to blue\n18. Finally draw a `circle` 10 pixels big\n\n#### What you’ll hack\nBecause you used a variable for all the different versions of the ghost’s body, you can change it once to see how the ghost’s body resizes! If you notice, the eyes position change with the ghostsize variable, but the eyes’ size don’t. Could you set up another variable that controls the size of the eyes?\n\n#### Briefing\nWhen you write a computer program you are telling a computer to do a series of tasks. And when you run the program, the computer reads all of the tasks and does them. So far we have written programs that will run the same way every single time you do the program, but what if we want the program to be different every time we run the program? If we wanted to vary the way in which the program works every time it was run, we need to use variables.\n\nA variable is a word that takes on the meaning of something else. And when you use it somewhere else it will pass on the word it means. In this challenge you will base the size of many of the ghost’s parts off of a variable. Changing the variable with a slider will then affect all of the different individual shapes sizes, giving you the power to make the whole ghost bigger or smaller at once!\n" +} diff --git a/lib/challenges/locales/ja/worlds/summercamp/backpack.json b/lib/challenges/locales/ja/worlds/summercamp/backpack.json new file mode 100644 index 000000000..fdb455022 --- /dev/null +++ b/lib/challenges/locales/ja/worlds/summercamp/backpack.json @@ -0,0 +1,143 @@ +{ + "id": "backpack", + "title": "Pack your things", + "short_title": "Backpack", + "icon_class": "challenge_backpack", + "description": "Dick Kelty is the inventor of the aluminium frame backpack. Kelty got the idea for his backpack in 1951 when he and a friend were hiking in the Sierra Nevada. Working in his garage, and with $500 borrowed against his house, Kelty and his wife went into production; he cut and welded the aluminium frames, while she stitched the nylon. They sold the finished backpacks for $24 apiece.", + "cover": "summercamp/day_8.png", + "completion_text": "I have a big challenge for you: try drawing your character behind that backpack! Head, arms, legs… ", + "difficulty": 1, + "startAt": 0, + "summerCamp": true, + "rewards": null, + "steps": [ + { + "hint": "It's a beautiful day to go for a walk in the forest - **type** `background blue`", + "solution": "background blue" + }, + { + "hint": "Firstly, set the `stroke` to `0`, to avoid drawing the outlines of the shapes", + "solution": "stroke 0" + }, + { + "hint": "Move the cursor to place the floor - in a new line **type** `moveTo 0, 250`", + "solution": "moveTo 0, 250" + }, + { + "hint": "Set the `color` of the grass to `green`", + "solution": "color green" + }, + { + "hint": "Draw the floor with a rectangle - **type** `rectangle 500, 250`", + "solution": "rectangle 500, 250" + }, + { + "hint": "This looks like a nice place for a tree - **type** `moveTo 220`", + "solution": "moveTo 220" + }, + { + "hint": "Set the `color` of the trunk to `lightbrown`", + "solution": "color lightbrown" + }, + { + "hint": "Draw the trunk with a `rectangle` of size `50` by `400`", + "solution": "rectangle 50, 400" + }, + { + "hint": "Beautiful! Now it just needs some leaves - **type** `move 30, -120` to place them", + "solution": "move 30, -120" + }, + { + "hint": "Set the `color` of the leaves to `darkgreen`", + "solution": "color darkgreen" + }, + { + "hint": "Draw a `circle` to represent the leaves with size `200`", + "solution": "circle 200" + }, + { + "hint": "Looking great! Let's move the cursor to place our backpack - **type** `moveTo 150, 200`", + "solution": "moveTo 150, 200" + }, + { + "hint": "Let's choose `color` `brown` for our backpack", + "solution": "color brown" + }, + { + "hint": "Draw the main part of the rucksack with a square - **type** `square 200`", + "solution": "square 200" + }, + { + "hint": "Now move the cursor to bottom part of our backpack - **type** `moveTo 250, 400`", + "solution": "moveTo 250, 400" + }, + { + "hint": "Draw the bottom using an ellipse - **type** `ellipse 100, 30`", + "solution": "ellipse 100, 30" + }, + { + "hint": "We need to store the sleeping bag at the top - **type** `moveTo 250, 200`", + "solution": "moveTo 250, 200" + }, + { + "hint": "Set the `color` of the sleeping bag to `darkred`", + "solution": "color darkred" + }, + { + "hint": "Ready to draw the sleeping bag? Use an ellipse - **type** `ellipse 115, 40`", + "solution": "ellipse 115, 40" + }, + { + "hint": "We need something to secure your sleeping bag to your backpack - **type** `moveTo 200, 160`", + "solution": "moveTo 200, 160" + }, + { + "hint": "The `orangered` seems like a nice `color` for the holders", + "solution": "color orangered" + }, + { + "hint": "Draw the left one first - **type** `rectangle 15, 90`", + "solution": "rectangle 15, 90" + }, + { + "hint": "Position the cursor to the right to draw the next holder - **type** `moveTo 290, 160`", + "solution": "moveTo 290, 160" + }, + { + "hint": "Use a `rectangle` again for the right holder, same as the previous one", + "solution": "rectangle 15, 90" + }, + { + "hint": "Excellent! We need more storage space. Move the cursor to the middle - **type** `moveTo 205, 320`", + "solution": "moveTo 205, 320" + }, + { + "hint": "Use a `rectangle` for the outside pocket, `90` by `60` will suffice", + "solution": "rectangle 90, 60" + }, + { + "hint": "That pocket needs to be closed so bugs can't get in - **type** `moveTo 250, 320`", + "solution": "moveTo 250, 320" + }, + { + "hint": "Set the `color` to `lightbrown`", + "solution": "color lightbrown" + }, + { + "hint": "An `ellipse` of size `48` by `7` will help here", + "solution": "ellipse 48, 7" + }, + { + "hint": "Looking great! Let’s place a button on that pocket - **type** `moveTo 250, 330`", + "solution": "moveTo 250, 330" + }, + { + "hint": "Set the `color` to `brown`", + "solution": "color brown" + }, + { + "hint": "Draw a `circle` button of size `10`", + "solution": "circle 10" + } + ] +} diff --git a/lib/challenges/locales/ja/worlds/summercamp/bear.json b/lib/challenges/locales/ja/worlds/summercamp/bear.json new file mode 100644 index 000000000..3282e8b5c --- /dev/null +++ b/lib/challenges/locales/ja/worlds/summercamp/bear.json @@ -0,0 +1,91 @@ +{ + "id": "bear", + "title": "Cheeky Bear", + "short_title": "Bear", + "description": "Bears are very smart and have been known to roll rocks into bear traps to set off the trap and then eat the bait in safety. These animals can run up to 40 miles per hour, fast enough to catch a running horse. Take into account that the fastest known human alive today is Usain Bolt, who can run at 27mph! And because bears can walk short distances on their hind legs, some Native Americans called them “the beast that walks like a man.”", + "icon_class": "challenge_bear", + "cover": "summercamp/day_11.png", + "completion_text": "That cute bear needs a body, and a habitat. Use your code skills to impress other campers with your abilities! Remember that the icons on your left can help you achieve what you have in mind.", + "difficulty": 1, + "startAt": 0, + "summerCamp": true, + "rewards": null, + "steps": [ + { + "hint": "The bear lives in the forest. Set the background color to green - **type** `background green`", + "solution": "background green" + }, + { + "hint": "The bear has brown fur, let's start to draw his face by getting our paint ready - **type** `color brown`", + "solution": "color brown" + }, + { + "hint": "Set the stroke to 0, to avoid drawing lines - **type** `stroke 0`", + "solution": "stroke 0" + }, + { + "hint": "Draw the face with a circle - **type** `circle 100`", + "solution": "circle 100" + }, + { + "hint": "Now let's move the cursor to draw his left ear - **type** `move -80, -80`", + "solution": "move -80, -80" + }, + { + "hint": "Draw the ear with a `circle` of size `30`", + "solution": "circle 30" + }, + { + "hint": "Move the cursor to the right to draw his other ear - **type** `move 160`", + "solution": "move 160" + }, + { + "hint": "Draw another ear (just like the last one)", + "solution": "circle 30" + }, + { + "hint": "Now head over to where the left eye will go - **type** `move -110, 50`", + "solution": "move -110, 50" + }, + { + "hint": "The rest of the bear's facial features will be `black`, so lets set the `color`", + "solution": "color black" + }, + { + "hint": "Draw the first eye - **type** `circle 5`", + "solution": "circle 5" + }, + { + "hint": "Next move over to where the other eye goes - **type** `move 60`", + "solution": "move 60" + }, + { + "hint": "Fill in the other eye just like the last one", + "solution": "circle 5" + }, + { + "hint": "Move to the center of the face for the bear's most distinctive feature - **type** `move -30, 50`", + "solution": "move -30, 50" + }, + { + "hint": "Draw his nose with a triangle using polygon - **type** `polygon 12, -16, -12, -16`", + "solution": "polygon 12, -16, -12, -16" + }, + { + "hint": "Let's get ready to draw the mouth by moving down a bit further - **type** `move 0, 20`", + "solution": "move 0, 20" + }, + { + "hint": "Set the `stroke` (the outline of a shape) to color `black` and size `3`", + "solution": "stroke black, 3" + }, + { + "hint": "We don't want the mouth to be filled so set its color to null - **type** `color null`", + "solution": "color null" + }, + { + "hint": "An arc is part of a cirlce, just like a smiling mouth - **type** `arc 15, 0.5, 2`", + "solution": "arc 15, 0.5, 2" + } + ] +} diff --git a/lib/challenges/locales/ja/worlds/summercamp/bow_and_arrow.json b/lib/challenges/locales/ja/worlds/summercamp/bow_and_arrow.json new file mode 100644 index 000000000..73a61d1f7 --- /dev/null +++ b/lib/challenges/locales/ja/worlds/summercamp/bow_and_arrow.json @@ -0,0 +1,107 @@ +{ + "id": "bow_and_arrow", + "title": "Bow and Arrow", + "short_title": "Bow and Arrow", + "icon_class": "challenge_bow", + "description": "Shooting a bow and arrow at a target is an art that requires lots of focus. This challenge is to draw a bow and try to hold it steady while your hand jitters...just like the other humans who have used the bow and arrow for hunting since the dawn of civilization over ten thousand years ago. The oldest known bow, found in Denmark, dates from 9000 BCE!", + "cover": "summercamp/day_15.png", + "completion_text": "Click Refresh and watch the target move while you try to hold your bow steady! Try getting rid of the moving background to make it easier to hit the target, converting your bow to a crossbow, or drawing an arrow in the bullseye.", + "difficulty": 1, + "startAt": 0, + "summerCamp": true, + "rewards": null, + "steps": [ + { + "hint": "The weather is good today...there is no wind to blow our arrows off course. Set the background color to blue - **type** `background blue`.", + "solution": "background blue" + }, + { + "hint": "We want the background to jitter, so we will start drawing it at a random point. **Type** `moveTo (random -20, 0), (random 240, 260)`.", + "solution": "moveTo (random -20, 0), (random 240, 260)" + }, + { + "hint": "Our target is in a grassy field, so lets get our `color green` ready", + "solution": "color green" + }, + { + "hint": "Draw a big `rectangle` that is `550` pixels high and `300` pixels wide for the grass", + "solution": "rectangle 550, 300" + }, + { + "hint": "Now let's move the cursor to draw our target - **type** `move 275, 10`", + "solution": "move 275, 10" + }, + { + "hint": "First we will draw the wooden legs supporting it - **type** `stroke brown, 15`", + "solution": "stroke brown, 15" + }, + { + "hint": "Draw the left leg - **type** `line -80, 120`", + "solution": "line -80, 120" + }, + { + "hint": "...and now draw the right leg - **type** `line 80, 120`", + "solution": "line 80, 120" + }, + { + "hint": "We will draw a target with white and red rings - **type** `stroke white, 50`", + "solution": "stroke white, 50" + }, + { + "hint": "Now make the inside of the circle red - **type** `color red`", + "solution": "color red" + }, + { + "hint": "First, draw a circle with a radius of 80 pixels- **type** `circle 80`", + "solution": "circle 80" + }, + { + "hint": "Second, draw a `circle` with a radius of `30` pixels", + "solution": "circle 30" + }, + { + "hint": "Move the cursor to draw an arrowhead - **type** `moveTo 250, 220`", + "solution": "moveTo 250, 220" + }, + { + "hint": "Our arrowhead will have a thin gray outline - **type** `stroke gray, 1`", + "solution": "stroke gray, 1" + }, + { + "hint": "The flint arrowhead is going to have the `color dimgray`", + "solution": "color dimgray" + }, + { + "hint": "Draw the arrowhead as a diamond - **type** `polygon -10, 40, 0, 80, 10, 40`", + "solution": "polygon -10, 40, 0, 80, 10, 40" + }, + { + "hint": "Next we will move to draw the shaft of the arrow - **type** `move 0, 40`", + "solution": "move 0, 40" + }, + { + "hint": "The arrow will be made of a light brown wood - **type** `stroke lightbrown, 20`", + "solution": "stroke lightbrown, 20" + }, + { + "hint": "Draw a line for the shaft - **type** `line 200, 360`", + "solution": "line 200, 360" + }, + { + "hint": "The last thing we will draw is our bow. Move the cursor off the screen - **type** `moveTo 800, 375`", + "solution": "moveTo 800, 375" + }, + { + "hint": "We are going to draw an arc for the bow so let's draw it with a thick piece of dark brown wood - **type** `stroke darkbrown, 40`", + "solution": "stroke darkbrown, 40" + }, + { + "hint": "We don't want the arc to have any fill - **type** `color null`", + "solution": "color null" + }, + { + "hint": "Draw the bow with a big arc centered far off the screen - **type** `arc 500, 0, 2`", + "solution": "arc 500, 0, 2" + } + ] +} diff --git a/lib/challenges/locales/ja/worlds/summercamp/camera.json b/lib/challenges/locales/ja/worlds/summercamp/camera.json new file mode 100644 index 000000000..0a53047ee --- /dev/null +++ b/lib/challenges/locales/ja/worlds/summercamp/camera.json @@ -0,0 +1,109 @@ +{ + "id": "camera", + "title": "Take a pic!", + "short_title": "Camera", + "icon_class": "challenge_camera", + "description": "Back in the 1820s, early cameras would take several hours to actually capture a film! With annoyingly long exposure hours, photographing people with a nice smile was not really possible. Why? Try and hold a convincing smile while staying perfectly still for hours and you will get your answer. Today, the number of photographs clicked every two minutes is same as the number of photographs clicked by mankind in 1800s.", + "cover": "summercamp/day_10.png", + "completion_text": "Try drawing yourself taking the picture behind that beautiful camera. Perhaps a light for the flash as well?", + "difficulty": 1, + "startAt": 0, + "summerCamp": true, + "rewards": { + "outfit": 1 + }, + "steps": [ + { + "hint": "Set the `background` color to `blue`", + "solution": "background blue" + }, + { + "hint": "Set the `stroke` to `0` for now, to avoid drawing the outline of the shapes", + "solution": "stroke 0" + }, + { + "hint": "Move the cursor to place the camera in the center - **type** `moveTo 100, 150`", + "solution": "moveTo 100, 150" + }, + { + "hint": "Set the `color` of the camera to `dimgray`", + "solution": "color dimgray" + }, + { + "hint": "Now draw the body of the camera with a rectangle - **type** `rectangle 300, 200`", + "solution": "rectangle 300, 200" + }, + { + "hint": "Move the cursor to draw the lense - **type** `move 150, 100`", + "solution": "move 150, 100" + }, + { + "hint": "Set the `color` of the lens to `lightblue`", + "solution": "color lightblue" + }, + { + "hint": "Set the outline of the lens with a `stroke` of `black` color and size `10`", + "solution": "stroke black, 10" + }, + { + "hint": "The lens is a `circle` with size `50`", + "solution": "circle 50" + }, + { + "hint": "Set the `color` to `lightgray` for the second half of the lens", + "solution": "color lightgray" + }, + { + "hint": "Draw an arc that matches the top half of the lens - **type** `arc 50, 2, 1`", + "solution": "arc 50, 2, 1" + }, + { + "hint": "This camera needs a flash! Move the cursor to place it - **type** `move -30, -125`", + "solution": "move -30, -125" + }, + { + "hint": "Draw the flash of the camera with a `rectangle` of size `60` by `20`", + "solution": "rectangle 60, 20" + }, + { + "hint": "Set the `stroke` back to `0`.", + "solution": "stroke 0" + }, + { + "hint": "Set the `color` of the flash to `lightblue`", + "solution": "color lightblue" + }, + { + "hint": "Draw a polygon for the reflection on the flash - **type** `polygon 40, 0, 0, 20`", + "solution": "polygon 40, 0, 0, 20" + }, + { + "hint": "Only the button to shoot the picture is left - **type** `move 100, 10`", + "solution": "move 100, 10" + }, + { + "hint": "Set the `color` of the button to `red`.", + "solution": "color red" + }, + { + "hint": "Draw the button of the camera with a `rectangle` of size `50` by `15`", + "solution": "rectangle 50, 15" + }, + { + "hint": "One more detail! Move the cursor one last time - **type** `move 25, -20`", + "solution": "move 25, -20" + }, + { + "hint": "Set the `color` to `yellow`", + "solution": "color yellow" + }, + { + "hint": "Set the `font` to `'ComicSansMS'` and size `30`", + "solution": "font 'ComicSansMS', 30" + }, + { + "hint": "Write some text - **type** `text 'Click!'`", + "solution": "text 'Click!'" + } + ] +} diff --git a/lib/challenges/locales/ja/worlds/summercamp/camp_badge.json b/lib/challenges/locales/ja/worlds/summercamp/camp_badge.json new file mode 100644 index 000000000..f682de7bc --- /dev/null +++ b/lib/challenges/locales/ja/worlds/summercamp/camp_badge.json @@ -0,0 +1,56 @@ +{ + "id": "camp_badge", + "title": "Camp Badge", + "short_title": "Camp Badge", + "icon_class": "challenge_badge", + "description": "First Aid is the most popular merit badge. In fact, 6.9 million Scouts have earned it since its debut in 1911. Other popular ones are Environmental Science, Search and Rescue, and our favourites Programming and Game Design! There are some oddballs as well. For example Truck transportation: “Assume that you are going to ship by truck 500 pounds of goods (freight class 65) from your town to another town 500 miles away. Your shipment must arrive within three days. Explain in writing…”. And Nuclear Science “Obtain a sample of irradiated and non-irradiated foods. Prepare the two foods and compare their taste and texture.”", + "completion_text": "This badge will distinguish your camp from others. Surprise the world with an amazing creation.", + "cover": "summercamp/day_5.png", + "difficulty": 1, + "startAt": 4, + "start_date": "2015-10-07 06:00:00", + "summerCamp": true, + "rewards": null, + "steps": [ + { + "hint": "Set the `background` color to `black`", + "solution": "background black" + }, + { + "hint": "Set the `color` of your badge to `lightblue`", + "solution": "color lightblue" + }, + { + "hint": "Set the stroke for the first circle - **type** `stroke red, 20`", + "solution": "stroke red, 20" + }, + { + "hint": "Draw a `circle` with a size of `200`", + "solution": "circle 200" + }, + { + "hint": "Set the stroke for the second circle - **type** `stroke yellow, 20`", + "solution": "stroke yellow, 20" + }, + { + "hint": "Draw a `circle` with a size of `190`", + "solution": "circle 190" + }, + { + "hint": "Set the `stroke` for the third circle to `purple` color and size `20`", + "solution": "stroke purple, 20" + }, + { + "hint": "Draw a `circle` with a size of `180`", + "solution": "circle 180" + }, + { + "hint": "Add some decoration inside. Set the `color` to `green`", + "solution": "color green" + }, + { + "hint": "An arc is part of a cirlce, draw one that matches the inner circle - **type** `arc 180, 1, 2`", + "solution": "arc 180, 1, 2" + } + ] +} diff --git a/lib/challenges/locales/ja/worlds/summercamp/camp_sign.json b/lib/challenges/locales/ja/worlds/summercamp/camp_sign.json new file mode 100644 index 000000000..7b952989f --- /dev/null +++ b/lib/challenges/locales/ja/worlds/summercamp/camp_sign.json @@ -0,0 +1,87 @@ +{ + "id": "camp_sign", + "title": "Your Summer Camp sign", + "short_title": "Camp Sign", + "description": "Welcome to your first day! Before you set out from the lodge, your campsite sign needs a design. Be creative! Use a crazy color scheme, or show what you want to do at camp. \nIn the Pacific Northwest of the United States, indigenous peoples carved Totem Poles to tell the stories of their families and cultures. These beautiful sculptures are carved into trees and often feature characters and events from legends. You can search the internet for images of Totem Poles for inspiration.", + "icon_class": "challenge_campsign", + "cover": "summercamp/day_1.png", + "completion_text": "Well done! Now give your camp its own name and style. Change your camp name on line 18, or the color of the sign on line 3... why not add a nice background and some extra decorations? All those tool icons on the left can help you get started.", + "difficulty": 1, + "startAt": 0, + "summerCamp": true, + "rewards": null, + "steps": [ + { + "hint": "It's a sunny day! Set the background color to blue - **type** `background blue`", + "solution": "background blue" + }, + { + "hint": "Let's move the cursor over to the place on the screen where we want to start drawing our sign.\n\nPress ENTER to add the next instruction, and - **type** `moveTo 100, 150`", + "solution": "moveTo 100, 150" + }, + { + "hint": "In Make Art we draw shapes using digital pens. Before we draw the next shape, we need to choose the pen we want to use to fill the inside of the shape. Let's select a brown pen by setting the color to lightbrown.\n\n In a new line **type** `color lightbrown`", + "solution": "color lightbrown" + }, + { + "hint": "When we draw a shape we can control how thick the line is that the pen leaves behind on the outside of the shape. This line is called the **stroke**.\n\n Press enter and then set the stroke to 0, to avoid drawing lines - **type** `stroke 0`", + "solution": "stroke 0" + }, + { + "hint": "Now that we have our pen all set up, we can get started on the sign!\n\nDraw the main billboard with a rectangle - **type** `rectangle 300, 200`", + "solution": "rectangle 300, 200" + }, + { + "hint": "Let's draw a shadow. Set the color to brown first - **type** `color brown`", + "solution": "color brown" + }, + { + "hint": "Draw a thin shadow with a rectangle - **type** `rectangle 300, 5`", + "solution": "rectangle 300, 5" + }, + { + "hint": "That sign looks too clean. We need to draw some imperfections.\n\nMove the cursor to place one on the left side of the sign- **type** `moveTo 100, 220`", + "solution": "moveTo 100, 220" + }, + { + "hint": "Our imperfection will be a triangle. First we need to set the `color` to `blue` to match the background.", + "solution": "color blue" + }, + { + "hint": "Set the stroke to be size 5 and brown (to match the sign). You can do both these things in one command - **type** `stroke brown, 5`", + "solution": "stroke brown, 5" + }, + { + "hint": "Now we will use the `polygon` command to draw a triangular imperfection. To create it, we need to list out the positions of the two other corners - **type** `polygon 16, 10, 0, 11`", + "solution": "polygon 16, 10, 0, 11" + }, + { + "hint": "The sign needs a post. Move the cursor to where we will draw it - **type** `moveTo 230, 350`", + "solution": "moveTo 230, 350" + }, + { + "hint": "Set the color of the post to brown - **type** `color brown` ", + "solution": "color brown" + }, + { + "hint": "Set the stroke to 0, again - **type** `stroke 0`", + "solution": "stroke 0" + }, + { + "hint": "Now that we have the colors sorted, draw the post with a rectangle - **type** `rectangle 40, 150`", + "solution": "rectangle 40, 150" + }, + { + "hint": "We need some text in that sign. Move the cursor to place the text - **type** `moveTo 250, 270`", + "solution": "moveTo 250, 270" + }, + { + "hint": "Next we need to choose our font. There are lots to choose from, like `Bariol`, `Georgia`, `Comic Sans MS`, `cursive`, and `Courier`.\n\nPick your favorite and type it in (inside of quote marks) like this - `font 'Bariol', 70`.", + "solution": "font 'Bariol', 70" + }, + { + "hint": "Now write some silly text - **type** `text 'My Camp'`", + "solution": "text 'My Camp'" + } + ] +} diff --git a/lib/challenges/locales/ja/worlds/summercamp/campfire.json b/lib/challenges/locales/ja/worlds/summercamp/campfire.json new file mode 100644 index 000000000..3b311f9ec --- /dev/null +++ b/lib/challenges/locales/ja/worlds/summercamp/campfire.json @@ -0,0 +1,90 @@ +{ + "id": "campfire", + "title": "Campfire", + "short_title": "Campfire", + "description": "Time to get a fire going. In the wilderness, this very well might be your only source of light, and heat. Burning at over a thousand degrees fahrenheit, this will be sure to keep you warm, and could keep you fed too! Meats, vegetables, and marshmallows can all be cooked over the open flame with the help of sharpened sticks. \nMost fires are built with wood logs, but yours is going to be built with code and a “loop.” As your fire grows upwards its colour changes into a deep shade of orange as the oxygen it is burning starts to cools down. Your code will produce hundreds of colours with just a few lines of code.", + "icon_class": "challenge_fire", + "completion_text": "Try adding a starry sky, more flames, a ring of rocks to make it safer or even marshmallows!", + "difficulty": 2, + "cover": "summercamp/day_6.png", + "startAt": 5, + "summerCamp": true, + "rewards": { + "wallpaper": 1 + }, + "steps": [ + { + "hint": "It's a dark night. Set the `background` color to `darkblue`", + "solution": "background darkblue" + }, + { + "hint": "Set the stroke to 0, to avoid drawing lines - **type** `stroke 0`", + "solution": "stroke 0" + }, + { + "hint": "Move the cursor to place the floor - **type** `moveTo 0, 300`", + "solution": "moveTo 0, 300" + }, + { + "hint": "Set the `color` to `darkgreen`", + "solution": "color darkgreen" + }, + { + "hint": "Draw the grass using a rectangle - **type** `rectangle 500, 200`", + "solution": "rectangle 500, 200" + }, + { + "hint": "Move the cursor to place the light casted by the fire - **type** `moveTo 250, 400`", + "solution": "moveTo 250, 400" + }, + { + "hint": "Set the `color` to `green`", + "solution": "color green" + }, + { + "hint": "Draw the light using an ellipse - **type** `ellipse 200, 30`", + "solution": "ellipse 200, 30" + }, + { + "hint": "We need some wood to feed the fire - **type** `moveTo 110, 390`", + "solution": "moveTo 110, 390" + }, + { + "hint": "Set the stroke for the logs - **type** `stroke brown, 25`", + "solution": "stroke brown, 25" + }, + { + "hint": "Good, now draw the first log - **type** `line 270, 30`", + "solution": "line 270, 30" + }, + { + "hint": "Move the cursor to place the second log - **type** `moveTo 420, 390`", + "solution": "moveTo 420, 390" + }, + { + "hint": "Draw the second log - **type** `line -290, 30`", + "solution": "line -290, 30" + }, + { + "hint": "Excellent! We are now ready to light the fire - **type** `moveTo 180, 400`", + "solution": "moveTo 180, 400" + }, + { + "hint": "Our fire will be formed by 150 lines! - **type** `for i in [ 1 .. 150 ]`", + "solution": "for i in [ 1 .. 150 ]" + }, + { + "hint": "Set the thickness and color of each line - **type** `stroke 'rgba(255, ' + (i + 50) + ', 0, 0.3)', 10`", + "solution": " stroke 'rgba(255, ' + (i + 50) + ', 0, 0.3)', 10", + "validate": "__^ stroke 'rgba*\\(255, ' \\+ \\(i *\\+ *50\\) *\\+ *', *0, *0.3\\)', 10" + }, + { + "hint": "Now draw the line - **type** `line 150 - i`", + "solution": " line 150 - i" + }, + { + "hint": "Move the cursor for next line - **type** `move 0.5, -2`", + "solution": " move 0.5, -2" + } + ] +} diff --git a/lib/challenges/locales/ja/worlds/summercamp/campsite.json b/lib/challenges/locales/ja/worlds/summercamp/campsite.json new file mode 100644 index 000000000..abce584fa --- /dev/null +++ b/lib/challenges/locales/ja/worlds/summercamp/campsite.json @@ -0,0 +1,97 @@ +{ + "id": "campsite", + "title": "Draw your Campsite", + "short_title": "Campsite", + "description": "Time to find a clearing to set up camp. The most important thing to look for when searching for an optimal campsite is flat ground. If possible, keep your campsite close to a water source. This will make cooking and cleanup much easier. Finally, make sure to be surrounded by trees, as they are a great source of kindling and will provide protection from the sun. \nYour friends will want to see what your campsite looks like, so once you have one, draw it! You can use code to set the scene for where you are staying for the next two weeks.", + "icon_class": "challenge_location", + "completion_text": "The camp site is looking great! Try adding more trees, flowers, rocks... perhaps a fence as well?", + "cover": "summercamp/day_2.png", + "difficulty": 1, + "startAt": 1, + "summerCamp": true, + "rewards": { + "outfit": 1 + }, + "steps": [ + { + "hint": "Today is a beautiful day - **type** `background blue`", + "solution": "background blue" + }, + { + "hint": "Set the stroke to 0, to avoid drawing lines - **type** `stroke 0`", + "solution": "stroke 0" + }, + { + "hint": "Move the cursor where the sun will be - **type** `moveTo 400, 50`", + "solution": "moveTo 400, 50" + }, + { + "hint": "Set the `color` of the sun `yellow`", + "solution": "color yellow" + }, + { + "hint": "Draw the sun with a circle - **type** `circle 40`", + "solution": "circle 40" + }, + { + "hint": "There is one cloud in the horizon. - **type** `moveTo 440, 80`", + "solution": "moveTo 440, 80" + }, + { + "hint": "Set the `color` of the cloud `white`", + "solution": "color white" + }, + { + "hint": "Draw the cloud with an ellipse - **type** `ellipse 60, 20`", + "solution": "ellipse 60, 20" + }, + { + "hint": "The lake has a beautiful `color` `aquamarine` this morning", + "solution": "color aquamarine" + }, + { + "hint": "Move the cursor where the lake is - **type** `moveTo 0, 190`", + "solution": "moveTo 0, 190" + }, + { + "hint": "Draw the lake using a simple rectangle - **type** `rectangle 500, 310`", + "solution": "rectangle 500, 310" + }, + { + "hint": "Set the `color` to `green` for the grass", + "solution": "color green" + }, + { + "hint": "Move the cursor before drawing the grass - **type** `moveTo 250, 700`", + "solution": "moveTo 250, 700" + }, + { + "hint": "Draw the camp site with a circle - **type** `circle 500`", + "solution": "circle 500" + }, + { + "hint": "Looking a bit empty, let's draw a tree - **type** `moveTo 120, 300`", + "solution": "moveTo 120, 300" + }, + { + "hint": "Set the `color` of the trunk to `brown`", + "solution": "color brown" + }, + { + "hint": "Draw the trunk of the tree using a rectangle - **type** `rectangle 15, 100`", + "solution": "rectangle 15, 100" + }, + { + "hint": "Now place the foliage of the tree - **type** `move 8, -120`", + "solution": "move 8, -120" + }, + { + "hint": "Set the `color` to `darkgreen`", + "solution": "color darkgreen" + }, + { + "hint": "Draw the foliage with a triangle using `polygon` - **type** `polygon -40, 160, 40, 160`", + "solution": "polygon -40, 160, 40, 160" + } + ] +} diff --git a/lib/challenges/locales/ja/worlds/summercamp/cinema.json b/lib/challenges/locales/ja/worlds/summercamp/cinema.json new file mode 100644 index 000000000..4393cb316 --- /dev/null +++ b/lib/challenges/locales/ja/worlds/summercamp/cinema.json @@ -0,0 +1,117 @@ +{ + "id": "cinema", + "title": "Relax watching a movie", + "short_title": "Cinema", + "icon_class": "challenge_cinema", + "description": "After playing a short movie presentation by the Skladanowsky brothers in 1895 which consisted of numerous very short 6-second films accompanied by a specially composed piece of music, the Berlin Wintergarten theatre in Mitte, Berlin, became known as the first ever movie theatre. Unfortunately the theatre was destroyed by bombs in 1944, during the Second World War.", + "cover": "summercamp/day_14.png", + "completion_text": "What good is a cinema without a movie playing? Go ahead and try drawing a scene from your favourite movie up on the big screen, and maybe a few friends to watch the film with you! Don't forget the popcorn!", + "difficulty": 2, + "startAt": 0, + "summerCamp": true, + "rewards": { + "wallpaper": 1 + }, + "steps": [ + { + "hint": "It's dark in the cinema. Set the `background` color to `black`", + "solution": "background black" + }, + { + "hint": "Set the `stroke` to `0` in a new line", + "solution": "stroke 0" + }, + { + "hint": "First, move the cursor to place the floor - **type** `moveTo 0, 300`", + "solution": "moveTo 0, 300" + }, + { + "hint": "Set the floor `color` to `gray`", + "solution": "color gray" + }, + { + "hint": "Draw the floor with a rectangle - **type** `rectangle 500, 200`", + "solution": "rectangle 500, 200" + }, + { + "hint": "Now, move the cursor to place the screen - **type** `moveTo 50, 20`", + "solution": "moveTo 50, 20" + }, + { + "hint": "Set the screen `color` to `white`", + "solution": "color white" + }, + { + "hint": "The screen is a perfect `rectangle` of size `400` by `250`", + "solution": "rectangle 400, 250" + }, + { + "hint": "Amazing! This theatre needs a curtain - **type** `moveTo 0`", + "solution": "moveTo 0" + }, + { + "hint": "Set the curtain `color` to `red`", + "solution": "color red" + }, + { + "hint": "Draw a vertical curtain as a `rectangle` of size `30` by `330`", + "solution": "rectangle 30, 330" + }, + { + "hint": "Now draw an horizontal curtain size `500` by `10` in the same way", + "solution": "rectangle 500, 10" + }, + { + "hint": "Looking great! Place the curtain on the right - **type** `move 470`", + "solution": "move 470" + }, + { + "hint": "Draw a vertical curtain, same as the one the left", + "solution": "rectangle 30, 330" + }, + { + "hint": "This theatre needs some seats for our audience - **type** `moveTo 0, 360`", + "solution": "moveTo 0, 360" + }, + { + "hint": "Set the outline of the seats with a `stroke` of `orangered` color and size `10`.", + "solution": "stroke orangered, 10" + }, + { + "hint": "Let's draw 3 rows and 6 columns of seats with a loop - **type** `for x in [ 1 .. 3 ]`", + "solution": "for x in [ 1 .. 3 ]" + }, + { + "hint": "Set the `color` of the seats to `red`", + "solution": " color red" + }, + { + "hint": "Now draw a `rectangle` for the seats, size `500` by `40`", + "solution": " rectangle 500, 40" + }, + { + "hint": "Move the cursor down to place the back of the seats - **type** `move 0, 50`", + "solution": " move 0, 50" + }, + { + "hint": "Inside the loop, open a second loop for the back of the seats - **type** `for y in [ 1 .. 6 ]`", + "solution": " for y in [ 1 .. 6 ]" + }, + { + "hint": "Set the `color` of the backseat to `darkred`", + "solution": " color darkred" + }, + { + "hint": "Brilliant! Almost there. Now draw the back of the seat with an arc - **type** `arc 60, 0, 1`", + "solution": " arc 60, 0, 1" + }, + { + "hint": "Now separate the seats `130` pixels to the right", + "solution": " move 130" + }, + { + "hint": "Last, make sure new rows are positioned correctly - Press **Enter**, then **Backspace** and **type** `move -800` inside the **first** loop", + "solution": " move -800" + } + ] +} diff --git a/lib/challenges/locales/ja/worlds/summercamp/compass.json b/lib/challenges/locales/ja/worlds/summercamp/compass.json new file mode 100644 index 000000000..4732d0453 --- /dev/null +++ b/lib/challenges/locales/ja/worlds/summercamp/compass.json @@ -0,0 +1,93 @@ +{ + "id": "compass", + "title": "A compass is an essential tool", + "short_title": "Compass", + "icon_class": "challenge_compass", + "description": "Essentially a compass is a magnet, generally a magnetized needle. Since opposites attract the southern pole of the needle is attracted to the Earth's natural magnetic north pole. Did you know that you can create your own simply with a paperclip, cork and a magnet?", + "cover": "summercamp/day_9.png", + "completion_text": "Now try adding the rest of the 'compass rose' components: the other cardinal directions (E, S, W and even NE, NW, SE and SW). Why not a hand holding it?", + "difficulty": 1, + "startAt": 0, + "summerCamp": true, + "rewards": { + "wallpaper": 1 + }, + "steps": [ + { + "hint": "Select `lightgray` for the `background`", + "solution": "background lightgray" + }, + { + "hint": "In a new line, set the outline of your compass with a `stroke` of `gold` color and size `20`", + "solution": "stroke gold, 20" + }, + { + "hint": "Set the `color` of the compass to `gray`", + "solution": "color gray" + }, + { + "hint": "Your compass is a `circle` with size `110`", + "solution": "circle 110" + }, + { + "hint": "Set the `color` to `darkgray` for the second half of the compass", + "solution": "color darkgray" + }, + { + "hint": "Set the `stroke` back to `0`", + "solution": "stroke 0" + }, + { + "hint": "Draw an arc that matches the top half of the compass - **type** `arc 105, 2, 1`", + "solution": "arc 105, 2, 1" + }, + { + "hint": "We need to mark the north somehow - in a new line **type** `moveTo 250, 175`", + "solution": "moveTo 250, 175" + }, + { + "hint": "Set the `color` to `gold`", + "solution": "color gold" + }, + { + "hint": "Set the `font` to `'cursive'` and size `25`", + "solution": "font 'cursive', 25" + }, + { + "hint": "Write an N to represent north - **type** `text 'N'`", + "solution": "text 'N'" + }, + { + "hint": "Now we need a needle with 2 sides. Set the `color` to `red` for the first side", + "solution": "color red" + }, + { + "hint": "Move the cursor to position the needle **type** `moveTo 230, 250`", + "solution": "moveTo 230, 250" + }, + { + "hint": "Draw a triangle with a polygon - **type** `polygon 20, -90, 40, 0`", + "solution": "polygon 20, -90, 40, 0" + }, + { + "hint": "Excellent! Set the `color` to `white` for the second side of the needle", + "solution": "color white" + }, + { + "hint": "Draw the second part - **type** `polygon 20, 90, 40, 0`", + "solution": "polygon 20, 90, 40, 0" + }, + { + "hint": "Finish it with one last detail. Set the `color` to `gold`", + "solution": "color gold" + }, + { + "hint": "Move the cursor to the center of the compass **type** `move 20`", + "solution": "move 20" + }, + { + "hint": "Draw a `circle` of size `20`", + "solution": "circle 20" + } + ] +} diff --git a/lib/challenges/locales/ja/worlds/summercamp/fireworks.json b/lib/challenges/locales/ja/worlds/summercamp/fireworks.json new file mode 100644 index 000000000..ae830ff5e --- /dev/null +++ b/lib/challenges/locales/ja/worlds/summercamp/fireworks.json @@ -0,0 +1,50 @@ +{ + "id": "fireworks", + "title": "Fireworks", + "short_title": "Fireworks", + "icon_class": "challenge_fireworks", + "description": "Camp is almost all wrapped up, and to celebrate we have fireworks! Fireworks have been around for centuries and are believed to have been invented by the Chinese. We are almost ready to put on the show, but need a little bit of help designing the fireworks. Can you give it a shot?", + "cover": "summercamp/day_21.png", + "completion_text": "Well done! You made a function that can draw fireworks! Can you improve upon it? Draw them all over the screen, add in other creations and share it!", + "difficulty": 3, + "startAt": 0, + "summerCamp": true, + "rewards": null, + "steps": [ + { + "hint": "The sun is down and the moon is new, let’s make the sky dark with `background black`", + "solution": "background black" + }, + { + "hint": "Lets set the `stroke` to `red` for our firework", + "solution": "stroke red" + }, + { + "hint": "We want to draw 60 lines radiating outward, so let’s use a for loop `for i in [0 ... 60]`", + "solution": "for i in [0 ... 60]" + }, + { + "hint": "All of the lines in our firework should have different lengths! So for each line radiating out, let’s set its length with `length = random 1, 200`.", + "solution": " length = random 1, 200" + }, + { + "hint": "For each loop, we are drawing a new line radiating out. So for every time we loop, the angle of the line should change. This uses some advanced math, but don’t fear. Just **type** `angle = (360 / 60 * i) * (Math.PI / 180)`.", + "solution": " angle = (360 / 60 * i) * (Math.PI / 180)", + "validate": "__^ angle *= *\\(360 */ *60 \\* i\\) *\\* *\\(Math[.]PI */ *180\\) *$" + }, + { + "hint": "Using this new angle and the random length let’s calculate where the x coordinate for the end of the radiating line should be. **Type** `dx = 250 + Math.sin(angle) * length`.", + "solution": " dx = 250 + Math.sin(angle) * length", + "validate": "__^ dx *= *250 *\\+ *Math.sin\\(angle\\) *\\* *length" + }, + { + "hint": "Now let’s calculate the y coordinate for the end of the radiating line. **Type** `dy = 250 + Math.cos(angle) * length`.", + "solution": " dy = 250 + Math.cos(angle) * length", + "validate": "__^ dy *= *250 *\\+ *Math.cos\\(angle\\) *\\* *length" + }, + { + "hint": "Finally, with all the coordinates set we are ready to draw the line. **Type** `lineTo dx, dy` ", + "solution": " lineTo dx, dy" + } + ] +} diff --git a/lib/challenges/locales/ja/worlds/summercamp/fishing.json b/lib/challenges/locales/ja/worlds/summercamp/fishing.json new file mode 100644 index 000000000..1ddb8f591 --- /dev/null +++ b/lib/challenges/locales/ja/worlds/summercamp/fishing.json @@ -0,0 +1,107 @@ +{ + "id": "fishing", + "title": "Fishing", + "short_title": "Fishing", + "icon_class": "challenge_fishing", + "description": "It's time to go fishing! Inside the camp's lake there are trout, catfish, and perch swimming around looking for a snack. Grab your fishing pole and some worms, and head over to the water for todays adventure. ", + "cover": "summercamp/day_17.png", + "completion_text": "Great job! Every time you press a key the image redraws, so try holding down the space bar and watch the waves ripple. Also try adding a fish or making the bobber disappear.", + "difficulty": 2, + "startAt": 0, + "summerCamp": true, + "rewards": null, + "steps": [ + { + "hint": "It's a sunny day! Set the background color to lightblue - **type** `background lightblue`", + "solution": "background lightblue" + }, + { + "hint": "We will start by drawing the waves. We want to draw without a fill - set the `color` to be `null`.", + "solution": "color null" + }, + { + "hint": "Our waves will be dark blue - **type** `stroke darkblue, 8`", + "solution": "stroke darkblue, 8" + }, + { + "hint": "Move to the place on the left where we will start - **type** `moveTo 10, 250`", + "solution": "moveTo 10, 250" + }, + { + "hint": "We are going to draw waves on the surface by creating 25 waves inside of a loop - **type** `for i in [1 .. 25]`", + "solution": "for i in [1 .. 25]" + }, + { + "hint": "Create a wave out of an arc with a radius of 20 pixels - **type** `arc 20, 0.8, 0.2`", + "solution": " arc 20, 0.8, 0.2" + }, + { + "hint": "Move each wave a random amount to the left - **type** `move (random 24, 32)`", + "solution": " move (random 24, 32)" + }, + { + "hint": "Press ENTER and then backspace to get rid of the indent. This exits the loop.\n\nNext move to the place where we will draw the rest of the water - **type** `moveTo 0, 270`.", + "solution": "moveTo 0, 270" + }, + { + "hint": "Set the `color` of the water to be the same as the wave", + "solution": "color darkblue" + }, + { + "hint": "Draw a big `rectangle` that is `500` pixels high and `250` pixels wide for the water", + "solution": "rectangle 500, 250" + }, + { + "hint": "Let's get ready to add some little blue waves - **type** `stroke blue, 2`", + "solution": "stroke blue, 2" + }, + { + "hint": "We are going to draw waves 100 times - **type** `for i in [1 .. 100]`", + "solution": "for i in [1 .. 100]" + }, + { + "hint": "Move each wave to a random place on the surface of the water - **type** `moveTo (random 0, 500), (random 260, 500)`", + "solution": " moveTo (random 0, 500), (random 260, 500)" + }, + { + "hint": "Now draw each ripple as a little arc - **type** `arc 10, 0.8, 0.2`", + "solution": " arc 10, 0.8, 0.2" + }, + { + "hint": "Brilliant! When you press the spacebar, a new set of random numbers is selected and the ripples move!\n\nTo catch some fish we need a brown fishing pole - Exit the loop and **type** `stroke brown, 10`.", + "solution": "stroke brown, 10" + }, + { + "hint": "Now move to the place where we will draw the end of the pole - **type** `moveTo 300, 100`", + "solution": "moveTo 300, 100" + }, + { + "hint": "Draw a `line` that is `150` pixels wide and `400` pixels tall", + "solution": "line 150, 400" + }, + { + "hint": "Next we need some fishing line - **type** `stroke lightgray, 1`", + "solution": "stroke lightgray, 1" + }, + { + "hint": "Draw a line that goes to the left and down - **type** `line -100, 200`", + "solution": "line -100, 200" + }, + { + "hint": "To see if a fish is biting we are going to draw a cork. Move to the end of the fishing line - **type** `move -100, (random 197, 202)`", + "solution": "move -100, (random 197, 202)" + }, + { + "hint": "The cork doesn't have an outline - **type** `stroke 0`", + "solution": "stroke 0" + }, + { + "hint": "Set the cork's `color` to `red`", + "solution": "color red" + }, + { + "hint": "Now draw the cork floating in the water - `arc 8, 0, 1`", + "solution": "arc 8, 0, 1" + } + ] +} diff --git a/lib/challenges/locales/ja/worlds/summercamp/flag.json b/lib/challenges/locales/ja/worlds/summercamp/flag.json new file mode 100644 index 000000000..ea40cbe69 --- /dev/null +++ b/lib/challenges/locales/ja/worlds/summercamp/flag.json @@ -0,0 +1,77 @@ +{ + "id": "flag", + "title": "Create your Flag", + "short_title": "Flag", + "description": "Time to show your true colors. Your campsite is shaping up, and as the campsite’s leader you need to make a flag. We’ve got you started with the basics for a flag and flagpole, but it is up to you to to make it your own. \nYou can look to other flags for inspiration. Countries like France, Nigeria, Sweden, and Switzerland all have very simple color and shape designs, while Spain, Brazil, Kenya, and Saudi Arabia all feature complex designs. When you are done, share your flag to lay claim to your little bit of land!", + "icon_class": "challenge_flag", + "completion_text": "You have a white canvas in front of you, use it wisely. Create the most amazing flag the world has ever seen!", + "cover": "summercamp/day_4.png", + "difficulty": 1, + "startAt": 3, + "summerCamp": true, + "rewards": { + "outfit": 1 + }, + "steps": [ + { + "hint": "Draw the sky where the flag will flutter - **type** `background blue`", + "solution": "background blue" + }, + { + "hint": "Set the stroke to 0, to avoid drawing lines - **type** `stroke 0`", + "solution": "stroke 0" + }, + { + "hint": "Let's move the cursor to place our flagpole in the correct place - **type** `moveTo 100, 100`", + "solution": "moveTo 100, 100" + }, + { + "hint": "Set the `color` of the flagpole to `darkgray`", + "solution": "color darkgray" + }, + { + "hint": "Draw a long, thin pole with a rectangle - **type** `rectangle 10, 400`", + "solution": "rectangle 10, 400" + }, + { + "hint": "Move the cursor to place a ball on top-centre of the flagpole - **type** `move 5`", + "solution": "move 5" + }, + { + "hint": "Set the `color` of the ornament to `gold`", + "solution": "color gold" + }, + { + "hint": "Draw a circle with a size of 8 - in a new line **type** `circle 8`", + "solution": "circle 8" + }, + { + "hint": "Now move the cursor to start drawing our flag - **type** `moveTo 115, 123`", + "solution": "moveTo 115, 123" + }, + { + "hint": "Set the `color` of the flag to `white`", + "solution": "color white" + }, + { + "hint": "Draw the flag with a `rectangle` of size `261` and `171`", + "solution": "rectangle 261, 171" + }, + { + "hint": "That flag needs something to hold of to - **type** `moveTo 100, 140`", + "solution": "moveTo 100, 140" + }, + { + "hint": "Set the `color` of the holder to `brown`", + "solution": "color brown" + }, + { + "hint": "Draw the holder with a `20` by `5` `rectangle`", + "solution": "rectangle 20, 5" + }, + { + "hint": "Now is your turn! Draw an amazing pattern on it - **type** `moveTo 120, 125`", + "solution": "moveTo 120, 125" + } + ] +} diff --git a/lib/challenges/locales/ja/worlds/summercamp/flashlight.json b/lib/challenges/locales/ja/worlds/summercamp/flashlight.json new file mode 100644 index 000000000..a5a6781ce --- /dev/null +++ b/lib/challenges/locales/ja/worlds/summercamp/flashlight.json @@ -0,0 +1,93 @@ +{ + "id": "flashlight", + "title": "Lights on!", + "short_title": "Flashlight", + "icon_class": "challenge_flashlight", + "description": "Torches started life as ignited sticks; their flames would light the way for explorers and settlers. With the advent of electricity, and the invention of the dry cell battery in 1887, the road was paved to use incandescent bulbs as a replacement. While the technology inside flashlights has evolved, they are still as useful as ever. Meanwhile, the original torch has found a second coming in circus acts where they are thrown skywards in miraculous fashion.", + "cover": "summercamp/day_12.png", + "completion_text": "You are an adventurer in the dark with your torch. What might you have uncovered as its light passes over the room? Try drawing that fox that you’ve unearthed or that owl hooting in the trees.", + "difficulty": 1, + "startAt": 0, + "summerCamp": true, + "rewards": { + "outfit": 1 + }, + "steps": [ + { + "hint": "It's getting dark outside! Set the `background` color to `darkblue`", + "solution": "background darkblue" + }, + { + "hint": "Set the `stroke` to `0`, we won't need it for this challenge", + "solution": "stroke 0" + }, + { + "hint": "Move the cursor to place our flashlight - **type** `moveTo 200, 200`", + "solution": "moveTo 200, 200" + }, + { + "hint": "Set the `color` of the flashlight to `dimgray`", + "solution": "color dimgray" + }, + { + "hint": "Draw the head of the flashlight with a rectangle - **type** `rectangle 100, 50`", + "solution": "rectangle 100, 50" + }, + { + "hint": "Now move the cursor down to draw the neck - **type** `move 0, 50`", + "solution": "move 0, 50" + }, + { + "hint": "Set the `color` of this piece to `gray`", + "solution": "color gray" + }, + { + "hint": "Draw a polygon - **type** `polygon 20, 40, 80, 40, 100, 0`", + "solution": "polygon 20, 40, 80, 40, 100, 0" + }, + { + "hint": "Exciting! Now move the cursor down to draw the body - **type** `move 20, 40`", + "solution": "move 20, 40" + }, + { + "hint": "Set the `color` of the body to `darkgray`", + "solution": "color darkgray" + }, + { + "hint": "Draw the body of the flashlight with a `rectangle` `60` by `200`", + "solution": "rectangle 60, 200" + }, + { + "hint": "The only thing missing now is a ON/OFF button. Set the `color` to `dimgray`", + "solution": "color dimgray" + }, + { + "hint": "Now move the cursor down to place the button - **type** `move 30, 50`", + "solution": "move 30, 50" + }, + { + "hint": "Draw an ellipse where the button will be located - **type** `ellipse 10, 30`", + "solution": "ellipse 10, 30" + }, + { + "hint": "Set the `color` of the button to `red`", + "solution": "color red" + }, + { + "hint": "Draw the button with an ellipse - **type** `ellipse 10, 20`", + "solution": "ellipse 10, 20" + }, + { + "hint": "You have turned on the light! Set the color of the beam - **type** `color \"rgba(255, 255, 0, 0.8)\"`", + "solution": "color \"rgba(255, 255, 0, 0.8)\"" + }, + { + "hint": "Place the beam in front of the flashlight - **type** `move -50, -140`", + "solution": "move -50, -140" + }, + { + "hint": "Draw the beam of light with a polygon - **type** `polygon 100, 0, 180, -300, -80, -300`", + "solution": "polygon 100, 0, 180, -300, -80, -300" + } + ] +} diff --git a/lib/challenges/locales/ja/worlds/summercamp/foraging.json b/lib/challenges/locales/ja/worlds/summercamp/foraging.json new file mode 100644 index 000000000..2d2add721 --- /dev/null +++ b/lib/challenges/locales/ja/worlds/summercamp/foraging.json @@ -0,0 +1,57 @@ +{ + "id": "foraging", + "title": "Foraging", + "short_title": "Foraging", + "icon_class": "challenge_foraging", + "description": "The wild is full of plants and fauna to eat. From stinging nettles, to mushrooms, and a multitude of berries, any meal can be improved with naturally growing foods. Berries are common in many parts of the world, and at Camp Kano they run wild even though they are hard to find. You might need to use your coding skills to find them.", + "cover": "summercamp/day_19.png", + "completion_text": "But wait! Where are the berries you are meant to be foraging for? Use `color red`, `moveTo`, and `square 25` to add some extra berries to the scene!", + "difficulty": 1, + "startAt": 0, + "summerCamp": true, + "rewards": { + "wallpaper": 1 + }, + "steps": [ + { + "hint": "Set `stroke` to `0`", + "solution": "stroke 0" + }, + { + "hint": "It’s a bright sunny day! Set `background` to `blue`.", + "solution": "background blue" + }, + { + "hint": "Our foraging scene needs a grass field to start with. Set our drawing color to `green`.", + "solution": "color green" + }, + { + "hint": "We want our grass on the bottom half of the screen, so let’s move into position with `moveTo 0, 300`", + "solution": "moveTo 0, 300" + }, + { + "hint": "The grass is a nice big `rectangle` of size `500, 200`", + "solution": "rectangle 500, 200" + }, + { + "hint": "Now let’s add in a nice boxy tree to our foraging scene. Begin by moving into position at exactly `50, 100`.", + "solution": "moveTo 50, 100" + }, + { + "hint": "Our leaves are drawn with `square 150`.", + "solution": "square 150" + }, + { + "hint": "Next we need to draw the trunk. Move the cursor with `moveTo 100, 250`.", + "solution": "moveTo 100, 250" + }, + { + "hint": "Our wood has a nice `darkbrown` color. Set that as the drawing color.", + "solution": "color darkbrown" + }, + { + "hint": "The trunk is a `rectangle` with a width of `40` and a height of `150`", + "solution": "rectangle 40, 150" + } + ] +} diff --git a/lib/challenges/locales/ja/worlds/summercamp/ghost.json b/lib/challenges/locales/ja/worlds/summercamp/ghost.json new file mode 100644 index 000000000..7e6b445b3 --- /dev/null +++ b/lib/challenges/locales/ja/worlds/summercamp/ghost.json @@ -0,0 +1,91 @@ +{ + "id": "ghost", + "title": "Ghost gathering", + "short_title": "Ghost", + "description": "Boo! As night falls, the spirits come out to play. A recent poll reported 87% of Chinese office workers believed in ghosts, and according to another report, 25% of Britons say they have seen a ghost. It’s getting dark, so it is hard to see, but we think we found a ghost! Maybe you can find out if it is friendly or not with your creative coding powers.", + "icon_class": "challenge_ghost", + "completion_text": "Spooky! Can you make the ghost scarier? Maybe if it could say \"Boo!\"...", + "difficulty": 2, + "cover": "summercamp/day_7.png", + "startAt": 6, + "summerCamp": true, + "rewards": null, + "steps": [ + { + "hint": "Select a spooky color for the background - **type** `background darkpurple`", + "solution": "background darkpurple" + }, + { + "hint": "Set the `stroke` to `0`, to avoid drawing lines", + "solution": "stroke 0" + }, + { + "hint": "Set the `color` to `white` for the ghost", + "solution": "color white" + }, + { + "hint": "Now draw an ellipse for the ghost's body - **type** `ellipse 120, 140`", + "solution": "ellipse 120, 140" + }, + { + "hint": "Set the `color` to `black` for the eyes", + "solution": "color black" + }, + { + "hint": "Move the cursor to draw the first eye - **type** `move -40, -50`", + "solution": "move -40, -50" + }, + { + "hint": "Draw the eye with an ellipse - **type** `ellipse 20, 30`", + "solution": "ellipse 20, 30" + }, + { + "hint": "Set the `color` to `lightgray`", + "solution": "color lightgray" + }, + { + "hint": "Now draw a `circle` with a size of `5`", + "solution": "circle 5" + }, + { + "hint": "Looking good! Now move the cursor to the right for the second eye - **type** `move 30`", + "solution": "move 30" + }, + { + "hint": "Set the `color` back to `black` for the second eye", + "solution": "color black" + }, + { + "hint": "Draw the second eye with an ellipse - **type** `ellipse 20, 30`", + "solution": "ellipse 20, 30" + }, + { + "hint": "Set the `color` to `lightgray`", + "solution": "color lightgray" + }, + { + "hint": "Draw a `circle` with size `5`", + "solution": "circle 5" + }, + { + "hint": "Almost there! Set the `color` to `white`", + "solution": "color white" + }, + { + "hint": "Now move the cursor to the bottom - **type** `move -80, 150`", + "solution": "move -80, 150" + }, + { + "hint": "Let's open a loop - **type** `for i in [ 1 .. 5 ]`", + "solution": "for i in [ 1 .. 5 ]" + }, + { + "hint": "Draw a `circle` with a size of `45`", + "solution": " circle 45" + }, + { + "hint": "And move the cursor slightly to the right - **type** `move 45`", + "solution": " move 45" + } + ] +} diff --git a/lib/challenges/locales/ja/worlds/summercamp/guitar.json b/lib/challenges/locales/ja/worlds/summercamp/guitar.json new file mode 100644 index 000000000..a57697b83 --- /dev/null +++ b/lib/challenges/locales/ja/worlds/summercamp/guitar.json @@ -0,0 +1,127 @@ +{ + "id": "guitar", + "title": "Play a nice sweet song", + "short_title": "Guitar", + "icon_class": "challenge_guitar", + "description": "Did you know the oldest surviving guitar-like instrument is actually around 3,500 years old? It is a 3-string instrument with a plectrum suspended from the neck, it was owned by an Egyptian singer called Har-Mose and was buried alongside him - You can still see the instrument on display at the Archaeological Museum in Cairo, Egypt.", + "cover": "summercamp/day_13.png", + "completion_text": "What good is a guitar if we don't have a campfire to sing songs around? Try drawing a nice big campfire with some marshmallows for toasting! Maybe a big moon on the horizon too? Be wild, be creative!", + "difficulty": 2, + "startAt": 0, + "summerCamp": true, + "rewards": null, + "steps": [ + { + "hint": "It's a very nice night! Set the background color to darkblue - **type** `background darkblue`", + "solution": "background darkblue" + }, + { + "hint": "Set the `stroke` to `0` in a new line.", + "solution": "stroke 0" + }, + { + "hint": "Set your guitar `color` to `lightbrown`.", + "solution": "color lightbrown" + }, + { + "hint": "Move the cursor to place the guitar - **type** `moveTo 120, 250`", + "solution": "moveTo 120, 250" + }, + { + "hint": "Draw the first part of the body with an ellipse - **type** `ellipse 60, 65`", + "solution": "ellipse 60, 65" + }, + { + "hint": "Now for the second part of the body, `move` the cursor `70` pixels to the right.", + "solution": "move 70" + }, + { + "hint": "Draw a `circle` of size `55` for the second part of the guitar.", + "solution": "circle 55" + }, + { + "hint": "Every guitar needs a neck, move the cursor to place it - **type** `move 20, -10`", + "solution": "move 20, -10" + }, + { + "hint": "Set the neck `color` to `brown`.", + "solution": "color brown" + }, + { + "hint": "Draw the neck of the guitar with a rectangle - **type** `rectangle 150, 20`", + "solution": "rectangle 150, 20" + }, + { + "hint": "Now place the headstock - **type** `move 150, -5`", + "solution": "move 150, -5" + }, + { + "hint": "Draw the headstock with a `rectangle` of size `40` by `30`.", + "solution": "rectangle 40, 30" + }, + { + "hint": "Time to place the soundhole in the body - **type** `move -170, 15`", + "solution": "move -170, 15" + }, + { + "hint": "Set the outline of the soundhole with a `stroke` of `brown` color and size `10`.", + "solution": "stroke brown, 10" + }, + { + "hint": "Set the soundhole `color` to `black`.", + "solution": "color black" + }, + { + "hint": "Draw the hole with a `circle` of size `20`.", + "solution": "circle 20" + }, + { + "hint": "The bridge is the piece that fixes the strings to the body. Let's place it - **type** `move -50, -15`", + "solution": "move -50, -15" + }, + { + "hint": "Set the outline of the bridge with a `stroke` of `red` color and size `10`.", + "solution": "stroke red, 10" + }, + { + "hint": "Draw the bridge with a `rectangle` of size `2` by `35`.", + "solution": "rectangle 2, 35" + }, + { + "hint": "That's a good looking guitar. Time for the strings - **type** `move 0, 9`", + "solution": "move 0, 9" + }, + { + "hint": "Set the properties of the strings with a `stroke` of `white` color and size `1`.", + "solution": "stroke white, 1" + }, + { + "hint": "Let's draw the 4 strings with a loop - **type** `for i in [ 1 .. 4 ]`", + "solution": "for i in [ 1 .. 4 ]" + }, + { + "hint": "Draw a string using a line - **type** `line 250`", + "solution": " line 250" + }, + { + "hint": "And move the cursor slightly down to place the next ones - **type** `move 0, 4`", + "solution": " move 0, 4" + }, + { + "hint": "Press **Enter** and **Backspace** to set the `color` to `white` outside the loop", + "solution": "color white" + }, + { + "hint": "You are ready to play music! Start a new loop - **type** `for i in [ 1 .. 10 ]`", + "solution": "for i in [ 1 .. 10 ]" + }, + { + "hint": "Select a random location - **type** `moveTo (random 200, 400), (random 100, 400)`", + "solution": " moveTo (random 200, 400), (random 100, 400)" + }, + { + "hint": "Come on, play some notes! - **copy and paste** `text '♪'`", + "solution": " text '♪'" + } + ] +} diff --git a/lib/challenges/locales/ja/worlds/summercamp/hiking.json b/lib/challenges/locales/ja/worlds/summercamp/hiking.json new file mode 100644 index 000000000..b12407269 --- /dev/null +++ b/lib/challenges/locales/ja/worlds/summercamp/hiking.json @@ -0,0 +1,111 @@ +{ + "id": "hiking", + "title": "Hiking Poster", + "short_title": "Hiking", + "icon_class": "challenge_hiking", + "description": "The beautiful Camp Kano mountain range is known for its deep blue colour. The ten mountains in the range always seem to be changing position though, which makes for a dangerous climb. Should campers attempt to climb it? Who knows! But management wants an advertising posts so get to it.", + "cover": "summercamp/day_18.png", + "completion_text": "Well done, you’ve made a beautiful poster! Now play around with the random values and the text. What else is the poster missing?", + "difficulty": 1, + "startAt": 0, + "summerCamp": true, + "rewards": null, + "steps": [ + { + "hint": "Up above the clouds the sky is blue, **type** `background blue`", + "solution": "background blue" + }, + { + "hint": "Camp Kano’s mountains are a beautiful shade of dark blue. Set the drawing colour with `color darkblue`.", + "solution": "color darkblue" + }, + { + "hint": "The mountains also have a nice thick border, give them `stroke white, 10`", + "solution": "stroke white, 10" + }, + { + "hint": "Lets draw the ten mountains of Camp Kano with a loop! This will be much faster than drawing them individually. **Type** `for i in [ 0 ... 10 ]` to open the loop.", + "solution": "for i in [ 0 ... 10 ]" + }, + { + "hint": "For every time the loop runs, we want a mountain’s peak to be drawn randomly across the screen. Let’s select an x value with `x = random 0, 500`", + "solution": " x = random 0, 500" + }, + { + "hint": "However, for the y value, we only want each mountain’s peak to be drawn on the top part of the screen. **Type** `y = random 0, 200`", + "solution": " y = random 0, 200" + }, + { + "hint": "Now with our x and y values set we can move the cursor to them. **Type** `moveTo x, y`", + "solution": " moveTo x, y" + }, + { + "hint": "Draw a mountain for every loop with the polygon function. **Type** `polygon 400, 500, -400, 500`", + "solution": " polygon 400, 500, -400, 500" + }, + { + "hint": "First, get out of the previous for loop’s indent by pressing `BACKSPACE`. Now let’s draw some clouds with `stroke 0`", + "solution": "stroke 0" + }, + { + "hint": "Clouds are made of small droplets of water vapor, which is see-through! To get a see-through color we use the `opacity` function. **Type** `color (opacity white, .1)`", + "solution": "color (opacity white, .1)" + }, + { + "hint": "Now let’s make a new loop to draw the cloud puffs. We’ll need a lot, so let’s make this a loop last 300 iterations. **Type** `for j in [ 0 ... 250 ]`.", + "solution": "for j in [ 0 ... 250 ]" + }, + { + "hint": "We want cloud puffs sprinkled randomly across the screen, so lets choose an x value between 0 and 500 with`x = random 0, 500`", + "solution": " x = random 0, 500" + }, + { + "hint": "However, for the y value, we only want the cloud puffs to be drawn on the bottom part of the screen. **Type** `y = random 300, 500`", + "solution": " y = random 300, 500" + }, + { + "hint": "Now with our x and y values set we can move the cursor to them. **Type** `moveTo x, y`", + "solution": " moveTo x, y" + }, + { + "hint": "Let’s draw the cloud puff—a big transparent `circle` of size `100`", + "solution": " circle 100" + }, + { + "hint": "Press `BACKSPACE` once to get out of the indented line. Then lets move the cursor into place for some text with `moveTo 250, 350`", + "solution": "moveTo 250, 350" + }, + { + "hint": "Set the drawing color to red - **type** `color red`", + "solution": "color red" + }, + { + "hint": "Our message should be strong and impactful, so lets set the font to bold with `bold true`", + "solution": "bold true" + }, + { + "hint": "We also want to style our text with italics, do this with `italic true`", + "solution": "italic true" + }, + { + "hint": "Finally lets select Bariol at point size 40 with `font 'Bariol', 40`", + "solution": "font 'Bariol', 40" + }, + { + "hint": "Start your message off with `text 'Hike the Blue Mountains of'`", + "solution": "text 'Hike the Blue Mountains of'" + }, + { + "hint": "Now for a new line with a big bold finish. **Type** `font 90`", + "solution": "font 90" + }, + { + "hint": "Lets move the cursor down into place for the final line with `move 0, 90`", + "solution": "move 0, 90" + }, + { + "hint": "The finishing touch: **type** `text 'Camp Kano!'`", + "solution": "text 'Camp Kano!'" + } + ] +} diff --git a/lib/challenges/locales/ja/worlds/summercamp/index.json b/lib/challenges/locales/ja/worlds/summercamp/index.json new file mode 100644 index 000000000..a54bd7049 --- /dev/null +++ b/lib/challenges/locales/ja/worlds/summercamp/index.json @@ -0,0 +1,26 @@ +{ + + "challenges": [ + "./camp_sign", + "./campsite", + "./tent", + "./flag", + "./camp_badge", + "./campfire", + "./ghost", + "./backpack", + "./compass", + "./camera", + "./bear", + "./flashlight", + "./guitar", + "./cinema", + "./bow_and_arrow", + "./table_tennis", + "./fishing", + "./hiking", + "./foraging", + "./tree", + "./fireworks" + ] +} diff --git a/lib/challenges/locales/ja/worlds/summercamp/table_tennis.json b/lib/challenges/locales/ja/worlds/summercamp/table_tennis.json new file mode 100644 index 000000000..8e5a1fae0 --- /dev/null +++ b/lib/challenges/locales/ja/worlds/summercamp/table_tennis.json @@ -0,0 +1,121 @@ +{ + "id": "table_tennis", + "title": "Table Tennis", + "short_title": "Table Tennis", + "icon_class": "challenge_tennis", + "description": "Table Tennis is a game played with one or two people on each side of a table with the outline of a miniaturized tennis court drawn on it. Games are played to 11 or 21, and upon completion the victor’s paddle is thrown to the ground as they let out their battle cry.", + "cover": "summercamp/day_16.png", + "completion_text": "Well done! You made a beautiful 3D ping pong table. But there isn’t anyone playing or watching the game! Use your creativity and code to draw some fellow campers enjoying the game.", + "difficulty": 2, + "startAt": 0, + "summerCamp": true, + "rewards": { + "wallpaper": 1 + }, + "steps": [ + { + "hint": "Begin by setting your stroke to zero with `stroke 0`", + "solution": "stroke 0" + }, + { + "hint": "It's a sunny day! Set the background color to blue - **type** `background blue`", + "solution": "background blue" + }, + { + "hint": "Set your color to green for the grass. **Type** `color green`.", + "solution": "color green" + }, + { + "hint": "Move your cursor into place with `moveTo 0, 350`", + "solution": "moveTo 0, 350" + }, + { + "hint": "Cover the bottom part of the canvas with grass. Draw a `rectangle` of width `500` and height `150`.", + "solution": "rectangle 500, 150" + }, + { + "hint": "Give your table a solid foundation with some wood legs. Set `color` to `brown`", + "solution": "color brown" + }, + { + "hint": "Move the cursor into position for the first leg. **Type** `moveTo 20, 310`", + "solution": "moveTo 20, 310" + }, + { + "hint": "Now draw the first leg. Type `rectangle 15, 150`.", + "solution": "rectangle 15, 150" + }, + { + "hint": "Now the second leg. **Type** `moveTo 465, 310`.", + "solution": "moveTo 465, 310" + }, + { + "hint": "Now **draw** the second leg. Type `rectangle 15, 150`.", + "solution": "rectangle 15, 150" + }, + { + "hint": "And the third leg. **Type** `moveTo 40, 250`.", + "solution": "moveTo 40, 250" + }, + { + "hint": "Now draw the third leg the same size as the others", + "solution": "rectangle 15, 150" + }, + { + "hint": "Finally, the fourth leg. **Type** `moveTo 445, 250`.", + "solution": "moveTo 445, 250" + }, + { + "hint": "Now draw the fourth leg", + "solution": "rectangle 15, 150" + }, + { + "hint": "Now to put the table on! Set the drawing `color` to `darkgreen`.", + "solution": "color darkgreen" + }, + { + "hint": "Move your table top into place. Type `moveTo 10, 300`.", + "solution": "moveTo 10, 300" + }, + { + "hint": "Your table has perspective, to draw it use `polygon 30, -60, 450, -60, 480, 0`", + "solution": "polygon 30, -60, 450, -60, 480, 0" + }, + { + "hint": "For a cool 3D effect, lighten the drawing color with `color lighten darkgreen, 10`", + "solution": "color lighten darkgreen, 10" + }, + { + "hint": "**Draw** the side of the table with `rectangle 480, 10`", + "solution": "rectangle 480, 10" + }, + { + "hint": "For the net, set the drawing `color` to `white`", + "solution": "color white" + }, + { + "hint": "Move the cursor to **exactly** `moveTo 248, 220`", + "solution": "moveTo 248, 220" + }, + { + "hint": "Draw the net: a `rectangle` with a width of `4`, and height of `80`", + "solution": "rectangle 4, 80" + }, + { + "hint": "Give your scene a bouncing ball! Use random to decide what side of the table the ball should be on. **Type** `x = random 40, 460`.", + "solution": "x = random 40, 460" + }, + { + "hint": "Now we’ll use random to decide how high the ball should be! **Type** `y = random 150, 250`.", + "solution": "y = random 150, 250" + }, + { + "hint": "Move the cursor to the x and y variables you just made. **Type** `moveTo x, y`.", + "solution": "moveTo x, y" + }, + { + "hint": "Finally, draw your ball with a circle with radius 7. Type `circle 7`.", + "solution": "circle 7" + } + ] +} diff --git a/lib/challenges/locales/ja/worlds/summercamp/tent.json b/lib/challenges/locales/ja/worlds/summercamp/tent.json new file mode 100644 index 000000000..e0552bc87 --- /dev/null +++ b/lib/challenges/locales/ja/worlds/summercamp/tent.json @@ -0,0 +1,73 @@ +{ + "id": "tent", + "title": "Pitch your Tent", + "short_title": "Tent", + "description": "No campsite is complete without a tent. We’ve got you settled with a simple fly tent, which is usually made with a tarpaulin, rope, and stakes. But with your creative powers you can transform it into whatever you want! \nPeople have lived in tents, teepees, yurts, and wigwams for thousands of years. What features can you add to your tent to keep yourself dry and warm? You can always get inspiration from browsing other creations on Kano World, and searching the Internet for other tent designs.", + "icon_class": "challenge_setcamp", + "completion_text": "Nice job! You learnt in the last challenge how to draw a tree, why not adding it to the scene? Is that a bird flying in the sky?", + "cover": "summercamp/day_3.png", + "difficulty": 1, + "startAt": 2, + "summerCamp": true, + "rewards": { + "wallpaper": 1 + }, + "steps": [ + { + "hint": "Draw a sunny day - **type** `background lightblue`", + "solution": "background lightblue" + }, + { + "hint": "Set the stroke to 0, to avoid drawing lines - **type** `stroke 0`", + "solution": "stroke 0" + }, + { + "hint": "Move the cursor where the sun will be - **type** `moveTo 400, 50`", + "solution": "moveTo 400, 50" + }, + { + "hint": "Set the `color` of the sun `yellow`", + "solution": "color yellow" + }, + { + "hint": "Draw the sun with a circle - **type** `circle 40`", + "solution": "circle 40" + }, + { + "hint": "Move the cursor to draw some grass - **type** `moveTo 0, 350`", + "solution": "moveTo 0, 350" + }, + { + "hint": "Set the `color` of the grass `green`", + "solution": "color green" + }, + { + "hint": "Draw the grass using a rectangle - **type** `rectangle 500, 150`", + "solution": "rectangle 500, 150" + }, + { + "hint": "Excellent! Now we are ready to draw the tent - **type** `color red`", + "solution": "color red" + }, + { + "hint": "Position the cursor on top of the grass - **type** `moveTo 100, 350`", + "solution": "moveTo 100, 350" + }, + { + "hint": "Draw a triangle using `polygon` - **type** `polygon 150, -200, 300, 0`", + "solution": "polygon 150, -200, 300, 0" + }, + { + "hint": "We need the entrace now. Set the `color` to `darkred`", + "solution": "color darkred" + }, + { + "hint": "Place the cursor on the tip of the tent - **type** `moveTo 250, 150`", + "solution": "moveTo 250, 150" + }, + { + "hint": "Draw the entrance - **type** `polygon 30, 200, -30, 200`", + "solution": "polygon 30, 200, -30, 200" + } + ] +} diff --git a/lib/challenges/locales/ja/worlds/summercamp/tree.json b/lib/challenges/locales/ja/worlds/summercamp/tree.json new file mode 100644 index 000000000..0e190b858 --- /dev/null +++ b/lib/challenges/locales/ja/worlds/summercamp/tree.json @@ -0,0 +1,17 @@ +{ + "id": "tree", + "title": "Fractal Tree", + "short_title": "Tree", + "icon_class": "challenge_tree", + "description": "Time to play! Our counselors made you something to play with. A tree which can grow branches that expand outwards, and contract inwards. It can blossom fully, or shrivel to nothing. All with code. Make it yours.", + "cover": "summercamp/day_20.png", + "completion_text": "Play around with the blue numbers at the top of the code. What do they do? Why do they do that? Shape the tree to your liking. If things mess up, go back to the main menu and start again.", + "difficulty": 3, + "startAt": 0, + "summerCamp": true, + "rewards": { + "outfit": 1 + }, + "code": "# Play with these blue numbers\narmLength = 50\niterations = 9 # Might crash if you go over 15!\ndegreeChange = 20\nhasBlossoms = 3\nblossomSize = 70\nblossomOpacity = .02\n# ^^^ Play with these blue numbers ^^^\n\n###\nThis is a function that draws a tree\nbranch, when it completes, it calls itself\nover and over and over again until all the\ntree’s branches have been drawn!\n###\ndrawBranch = (x, y, branchesLeft, startAngle) ->\n if branchesLeft > 0 \n # Move to where the next branch should\n # be drawn:\n moveTo x, y\n \n # A branch is always blue, but the width\n # depends on how far from the base it is!\n stroke blue, branchesLeft \n \n # A bit of trigonometry here, it’s alright\n # if you don’t understand this! This \n # calculates coordinates for where the \n # branch should be drawn to, and where\n # the next branch should start.\n dx = Math.cos(startAngle) * armLength \n dy = -Math.sin(startAngle) * armLength \n \n # Draw a line to the new coordinates we\n # just calculated\n line dx, dy \n \n # This block of code only executes if\n # the current branch has blossoms. You\n # can change the hasBlossoms variable up\n # top!\n if branchesLeft <= hasBlossoms \n # Set the drawing color to a nice red\n color opacity \"rgb(247, 45, 99)\", blossomOpacity\n # Our blossoms shouldn’t have a stroke\n stroke 0 \n # Draw the blossom! These big blossoms\n # overlap over each other to create a\n # neat effect.\n circle blossomSize\n \n # Starts the next branch on the right\n drawBranch(x + dx, y + dy, branchesLeft - 1, startAngle - Math.PI / 180 * degreeChange) \n # Starts the next branch on the left\n drawBranch(x + dx, y + dy, branchesLeft - 1, startAngle + Math.PI / 180 * degreeChange)\n \n###\nFinally we call our function and see what\nhappens. Play with the numbers at the top of\nthe function and see how they change the tree\n###\ndrawBranch(stage.width * .5, stage.height, iterations, Math.PI / 2, length)", + "steps": [] +} diff --git a/lib/controller/feedback.js b/lib/controller/feedback.js index 8fe84cbf3..0d564a22c 100644 --- a/lib/controller/feedback.js +++ b/lib/controller/feedback.js @@ -12,7 +12,6 @@ var api, app.controller('FeedbackController', function ($scope, $rootScope, $routeParams) { api = $rootScope.api; - $scope.isFeedbackSplashOpen = false; $scope.loading = false; $scope.questions = null; $scope.error = ''; @@ -78,13 +77,11 @@ app.controller('FeedbackController', function ($scope, $rootScope, $routeParams) document.querySelector('.feedback-buttons').classList.add('hide'); setTimeout(function () { - $rootScope.isFeedbackSplashOpen = false; - $rootScope.$apply(); + $rootScope.feedback.closeModal(); }, 2500); } - $scope.handleSkip = function (e) { - e.preventDefault(); - $rootScope.isFeedbackSplashOpen = false; + $scope.closeModal = function () { + $rootScope.feedback.closeModal(); }; }); diff --git a/lib/directive/auth.js b/lib/directive/auth.js index 0656033fb..90621e805 100644 --- a/lib/directive/auth.js +++ b/lib/directive/auth.js @@ -1,5 +1,6 @@ "use strict"; -var app = require('../app'); +var i18n = require('../i18n'), + app = require('../app'); /* * Auth directive @@ -9,7 +10,7 @@ var app = require('../app'); app.directive('authForm', function () { return { restrict : 'E', - templateUrl : '/directive/auth.html', + templateUrl : i18n.getHtmlLocalePath() + '/directive/auth.html', scope : { mode: '=' }, diff --git a/lib/directive/display.js b/lib/directive/display.js index f2fe16f36..5754731d6 100644 --- a/lib/directive/display.js +++ b/lib/directive/display.js @@ -1,5 +1,6 @@ "use strict"; -var app = require('../app'), +var i18n = require('../i18n'), + app = require('../app'), session = require('../language/session'), fileUtil = require('../util/file'), td = require('throttle-debounce'), @@ -23,7 +24,7 @@ app.directive('display', function ($window, $timeout, $rootScope) { return { require : '^workspace', restrict : 'E', - templateUrl : '/directive/display.html', + templateUrl : i18n.getHtmlLocalePath() + '/directive/display.html', scope : { source : '=', mode : '=', diff --git a/lib/directive/editor-input.js b/lib/directive/editor-input.js index 44155d3de..fa7922ebe 100644 --- a/lib/directive/editor-input.js +++ b/lib/directive/editor-input.js @@ -1,4 +1,5 @@ -var app = require('../app'), +var i18n = require('../i18n'), + app = require('../app'), palette = require('../language/modules/palette.json'), docs = require('../../content/docs.json'), equal = require('deep-equal'), @@ -44,7 +45,7 @@ app.directive('editor', function ($rootScope, $controller, $compile) { return { require : '^workspace', restrict : 'E', - templateUrl : '/directive/editor.html', + templateUrl : i18n.getHtmlLocalePath() + '/directive/editor.html', scope : { ngModel : '=', editable : '=', @@ -605,4 +606,4 @@ function getAutoCompleteList() { }); return out; -} \ No newline at end of file +} diff --git a/lib/directive/editor.js b/lib/directive/editor.js index 91dbc710c..8222b1d91 100644 --- a/lib/directive/editor.js +++ b/lib/directive/editor.js @@ -1,6 +1,7 @@ "use strict"; -var app = require('../app'), +var i18n = require('../i18n'), + app = require('../app'), palette = require('../language/modules/palette.json'), config, docs = require('../../content/docs.json'), @@ -45,6 +46,7 @@ function initialiseEditor() { app.directive('editor', function ($rootScope, $controller, $compile, $routeParams, contentService) { config = $rootScope.cfg; + docs = docs[i18n.getLanguage() || 'en']; /* * Disable number handler on Pi version */ @@ -55,7 +57,7 @@ app.directive('editor', function ($rootScope, $controller, $compile, $routeParam return { require : '?workspace', restrict : 'E', - templateUrl : '/directive/editor.html', + templateUrl : i18n.getHtmlLocalePath() + '/directive/editor.html', scope : { ngModel : '=', editable : '=', diff --git a/lib/directive/export-modal.js b/lib/directive/export-modal.js index 414dda881..4fdb20e4a 100644 --- a/lib/directive/export-modal.js +++ b/lib/directive/export-modal.js @@ -1,5 +1,6 @@ "use strict"; var api, + i18n = require('../i18n'), app = require('../app'), WALLPAPER_RATIOS = { '1024': { @@ -25,7 +26,7 @@ var api, app.directive('exportModal', function ($rootScope, $routeParams) { return { restrict : 'E', - templateUrl : '/directive/export-modal.html', + templateUrl : i18n.getHtmlLocalePath() + '/directive/export-modal.html', scope : { display : '=', action : '=' diff --git a/lib/directive/progress-circle.js b/lib/directive/progress-circle.js index 5ae688911..752b4eb10 100644 --- a/lib/directive/progress-circle.js +++ b/lib/directive/progress-circle.js @@ -1,4 +1,5 @@ -var app = require('../app'); +var i18n = require('../i18n'), + app = require('../app'); var XMLNS = 'http://www.w3.org/2000/svg', RADIUS = 30, @@ -13,7 +14,7 @@ var XMLNS = 'http://www.w3.org/2000/svg', app.directive('progressCircle', function () { return { restrict : 'E', - templateUrl : '/directive/progress-circle.html', + templateUrl : i18n.getHtmlLocalePath() + '/directive/progress-circle.html', scope : { value : '=', max : '=' diff --git a/lib/directive/social.js b/lib/directive/social.js index 66cdc7174..bddc6d15a 100644 --- a/lib/directive/social.js +++ b/lib/directive/social.js @@ -1,5 +1,6 @@ "use strict"; -var app = require('../app'), +var i18n = require('../i18n'), + app = require('../app'), analytics = require('../core/analytics'), notify = require('../api/notify'); @@ -10,7 +11,7 @@ var app = require('../app'), app.directive('socialSharing', function ($rootScope, socialService, emailService) { return { restrict: 'E', - templateUrl: '/directive/social.html', + templateUrl : i18n.getHtmlLocalePath() + '/directive/social.html', scope: { type: '=' }, diff --git a/lib/i18n.js b/lib/i18n.js new file mode 100644 index 000000000..bf813d090 --- /dev/null +++ b/lib/i18n.js @@ -0,0 +1,54 @@ +var url = require('url'); + +var SUPPORTED_LOCALES = [ + 'ja', + 'en', + 'es-AR', +]; + +function getLanguage() { + var parsedUrl = url.parse(window.location.href, true); + + if (parsedUrl.query['lang'] !== undefined) { + var lang = parsedUrl.query['lang']; + if (SUPPORTED_LOCALES.indexOf(lang) > -1) { + return lang; + } + // not in supported languages so fall back to normal detection + } + + var language = window.navigator.languages ? window.navigator.languages[0] : + window.navigator.userLanguage || window.navigator.language || 'en', + p = language.indexOf('-'); + + // check if full locale is supported + if (SUPPORTED_LOCALES.indexOf(language) > -1) { + return language; + } + + language = language.toLowerCase(); + + // otherwise check that if just language is supported + language = (p > -1) ? language.substr(0, p) : language; + if (SUPPORTED_LOCALES.indexOf(language) > -1) { + return language; + } + // language is not supported so default to 'en' + return 'en'; +} + +function getChallengeLocalePath () { + var language = getLanguage(); + return language === 'en' ? '' : '/locales/' + language; +} + +function getHtmlLocalePath () { + var language = getLanguage(); + return '/locales/' + language; +} + +module.exports = { + getLanguage: getLanguage, + getHtmlLocalePath: getHtmlLocalePath, + getChallengeLocalePath: getChallengeLocalePath +}; diff --git a/lib/routes.js b/lib/routes.js index dc4756b25..66755467d 100644 --- a/lib/routes.js +++ b/lib/routes.js @@ -1,4 +1,5 @@ -var app = require('./app'); +var i18n = require('./i18n'), + app = require('./app'); /* * Routes module @@ -11,37 +12,37 @@ app.config(function ($routeProvider) { // Challenges selection view .when('/challenges', { - templateUrl : '/challenges.html', + templateUrl : i18n.getHtmlLocalePath() + '/challenges.html', controller : 'ChallengesController' }) // Challenge view (With challenge ID) .when('/challenge/:world/:id', { - templateUrl : '/challenge.html', + templateUrl : i18n.getHtmlLocalePath() + '/challenge.html', controller : 'ChallengeController' }) // Challenge view (With only worldID) .when('/challenges/:world/', { - templateUrl : '/challenges.html', + templateUrl : i18n.getHtmlLocalePath() + '/challenges.html', controller : 'ChallengesController' }) // Playground view .when('/playground', { - templateUrl : '/playground.html', + templateUrl : i18n.getHtmlLocalePath() + '/playground.html', controller : 'PlaygroundController' }) // Load share item by ID view .when('/share/:id', { - templateUrl : '/share.html', + templateUrl : i18n.getHtmlLocalePath() + '/share.html', controller : 'ShareController' }) // Launch a local share .when('/localLoad/:path*', { - templateUrl : '/share.html', + templateUrl : i18n.getHtmlLocalePath() + '/share.html', controller : 'LocalLaunchController' }) diff --git a/lib/service/content.js b/lib/service/content.js index bf26b372b..907f913da 100644 --- a/lib/service/content.js +++ b/lib/service/content.js @@ -1,12 +1,13 @@ "use strict"; var app = require("../app"), + i18n = require("../i18n"), _ = require('lodash'), config = window.CONFIG; app.factory('contentService', function ($http, $q, $rootScope) { function getWorlds () { var defer = $q.defer(), - url = config.CHALLENGES_URL + "/index.json"; + url = config.CHALLENGES_URL + i18n.getChallengeLocalePath() + "/index.json"; $http({ method: 'GET', url: url @@ -21,7 +22,7 @@ app.factory('contentService', function ($http, $q, $rootScope) { function getWorld(contentUrl) { var defer = $q.defer(), - url = config.CHALLENGES_URL + "/" + contentUrl + "/index.json"; + url = config.CHALLENGES_URL + i18n.getChallengeLocalePath() + "/" + contentUrl + "/index.json"; $http({ method: 'GET', url: url @@ -39,7 +40,7 @@ app.factory('contentService', function ($http, $q, $rootScope) { function getChallenge(world, challenge_id) { var defer = $q.defer(), - url = config.CHALLENGES_URL + "/worlds/" + world + "/" + challenge_id + ".json"; + url = config.CHALLENGES_URL + i18n.getChallengeLocalePath() + "/worlds/" + world + "/" + challenge_id + ".json"; $http({ method: 'GET', url: url diff --git a/locales/en/challenge.json b/locales/en/challenge.json new file mode 100644 index 000000000..7d23e4b56 --- /dev/null +++ b/locales/en/challenge.json @@ -0,0 +1,21 @@ +{ + "challenge_title": "Challenge {{ id }}:", + "start": "Start", + "hint": "Hint", + "next": "Next", + "done": "Done", + "can_you_hack_this_challenge": "Can you hack this challenge?", + "make_it_into_a_fathers_day_card": "Make it into a Father's day card!", + "now_sign_up_to_kano_world_to_share_your_creation": "Now sign-up to Kano World to share your creation and send a card to your dad!", + "share_your_fathers_day_card": "Share your Father's day card!", + "now_you_can_share_the_card_on_kano_world": "Now you can share the card on Kano World and share it to your dad!", + "challenges_completed": "Challenges completed", + "now_make_something_new": "Now make something new!", + "new_world_unlocked_play_now": "New world unlocked! Play Now - ", + "menu": "Menu", + "playground": "Playground", + "you_did_it_go_back_for_more_coding_fun": "You did it, go back for more coding fun!", + "hour_of_code": "Hour Of Code", + "solution": "Solution" +} + diff --git a/locales/en/challenges.json b/locales/en/challenges.json new file mode 100644 index 000000000..ab7e25abe --- /dev/null +++ b/locales/en/challenges.json @@ -0,0 +1,11 @@ +{ + "challenges": "Challenges", + "get_kano_updates": "Get Kano Updates", + "sign_up": "Sign Up", + "playground": "Playground", + "certificate": "Certificate", + "teachers_guide": "Teacher's Guide", + "latest_shares": "Latest Shares", + "browse_more": "Browse more" +} + diff --git a/locales/en/directive.json b/locales/en/directive.json new file mode 100644 index 000000000..175681e02 --- /dev/null +++ b/locales/en/directive.json @@ -0,0 +1,26 @@ +{ + "save_to_gallery": "save to gallery", + "save_drawing": "save drawing", + "title": "Title", + "description": "Description", + "save": "Save", + "skip": "Skip", + "save_wallpaper": "Save Wallpaper", + "login_to_your_account": "Login to Your Account", + "create_your_account": "Create your account", + "share": "Share", + "save": "Save", + "reset": "Reset", + "load": "Load", + "toggle_autocomplete": "Toggle autocomplete", + "autocomplete": "Autocomplete", + "toggle_fullscreen": "Toggle fullscreen", + "fullscreen": "Fullscreen", + "download_teachers_guide": "Download teacher's guide", + "click_plus_to_add_a_shape_1": "Click", + "click_plus_to_add_a_shape_2": "to add a shape to your code", + "download_teachers_guide": "Download teacher's guide", + "guide": "Guide", + "recipients_email_address": "Recipient\\'s email address", + "your_message": "Your message" +} diff --git a/locales/en/partial.json b/locales/en/partial.json new file mode 100644 index 000000000..e16e6252d --- /dev/null +++ b/locales/en/partial.json @@ -0,0 +1,32 @@ +{ + "pixel_hack": "Pixel Hack:", + "code_your_way_through_the_history": "code your way through the history of video game art.", + "welcome_to_pixel_hack": "Welcome to Pixel Hack", + "start_your_coding_adventure": "Start your coding adventure by drawing Pong and other retro games. Move on to master 8-bit art for your own Minecraft characters and more. Show us how you can hack our challenges. Earn your Pixel Master Badge.", + "happy_hacking": "Happy Hacking!", + "claim_your_pixel_hack_certificate": "Claim your Pixel Hack certificate.", + "visit_this_address_from_a_computer": "Visit this address from a computer with a connected printer to create your certificate.", + "discover_kano": "Discover Kano", + "login": "Login", + "logout": "Logout", + "feedback": "Feedback", + "whats_up": "What\\'s up?", + "thank_you": "Thank You!", + "send": "Send", + "load": "Load", + "load_from_where": "Load from where", + "your_kano": "Your Kano", + "internet": "Internet", + "share_by_email": "Share by email", + "enter_an_email_address": "Enter an email address", + "i_just_made_this_with_code": "I just made this with code! Want to try your own? It's easy, fun and for everyone", + "your_name": "Your name...", + "next_up": "Next up:", + "back_to_world": "'Back to ' + selectedWorld.name", + "come_back_tomorrow_to_continue": "Come back tomorrow to continue this challenge", + "share_on_facebook": "Share on Facebook", + "share_on_twitter": "Share on Twitter", + "email_address": "Email address", + "share_with_friends": "Share with friends:", + "skip_sharing": "Skip sharing" +} diff --git a/locales/ja/challenge.json b/locales/ja/challenge.json new file mode 100644 index 000000000..25cfe7dbd --- /dev/null +++ b/locales/ja/challenge.json @@ -0,0 +1,20 @@ +{ + "challenge_title": "{{ id }}チャレンジ:", + "start": "スタート", + "hint": "ヒント", + "next": "次へ", + "done": "終わり", + "can_you_hack_this_challenge": "これもチャレンジしてみるかい?", + "make_it_into_a_fathers_day_card": "父の日のカードにしよう!", + "now_sign_up_to_kano_world_to_share_your_creation": "さあ、Kanoワールドに登路し、作品を共有し、お父さんへカードを送ろう!", + "share_your_fathers_day_card": "父の日のカードを共有しよう!", + "now_you_can_share_the_card_on_kano_world": "よっし、Kanoワールドでカードを共有し、お父さんへ送られるよ!", + "challenges_completed": "チャレンジ完了!", + "now_make_something_new": "さあ、新しいものを作ろう!", + "new_world_unlocked_play_now": "新しいワールドに入れるよ! 早速遊ぼうー", + "menu": "メニュー", + "playground": "遊び場", + "you_did_it_go_back_for_more_coding_fun": "やったぜ! 戻って、コードでもっと遊ぼう!", + "hour_of_code": "ハウアー・オブ・コード", + "solution": "正解は…" +} diff --git a/locales/ja/challenges.json b/locales/ja/challenges.json new file mode 100644 index 000000000..858e922fe --- /dev/null +++ b/locales/ja/challenges.json @@ -0,0 +1,11 @@ +{ + "challenges": "チャレンジ一覧", + "get_kano_updates": "Kanoお知らせを受け取る", + "sign_up": "登録", + "playground": "遊び場", + "certificate": "証明書", + "teachers_guide": "講師用のガイド", + "latest_shares": "最新の共有", + "browse_more": "もっと見る" +} + diff --git a/locales/ja/directive.json b/locales/ja/directive.json new file mode 100644 index 000000000..7e1f153f6 --- /dev/null +++ b/locales/ja/directive.json @@ -0,0 +1,26 @@ +{ + "save_to_gallery": "ギャラリーへ保存", + "save_drawing": "描画を保存", + "title": "タイトル", + "description": "説明", + "save": "保存", + "skip": "スキップ", + "save_wallpaper": "壁紙を保存", + "login_to_your_account": "アカウントへログイン", + "create_your_account": "アカウントを作成", + "share": "共有", + "save": "保存", + "reset": "リセット", + "load": "読み込む", + "toggle_autocomplete": "オートコンプリート切り替え", + "autocomplete": "オートコンプリート", + "toggle_fullscreen": "全画面切り替え", + "fullscreen": "全画面", + "download_teachers_guide": "講師用ガイドをダウンロード", + "click_plus_to_add_a_shape_1": "形をコードに挿入するには、", + "click_plus_to_add_a_shape_2": "を押してみて", + "download_teachers_guide": "教師用のガイドをダウンロード", + "guide": "ガイド", + "recipients_email_address": "宛先のメールアドレス", + "your_message": "メッセージ" +} diff --git a/locales/ja/partial.json b/locales/ja/partial.json new file mode 100644 index 000000000..f5aa459cd --- /dev/null +++ b/locales/ja/partial.json @@ -0,0 +1,32 @@ +{ + "pixel_hack": "ピクセルハック:", + "code_your_way_through_the_history": "ビデオゲームのアート歴史をコードで歩んでみよう。", + "welcome_to_pixel_hack": "ピクセルハックへようこそ", + "start_your_coding_adventure": "ポングやその他のレトロなゲームからコードの冒険を始めよう。次に8ビットアートをマスターし、自分のマインクラフトキャラクターなど作ろう。乗り越えたチャレンジを皆に見せて、ピクセルマスターのバッジをゲットしよう。", + "happy_hacking": "ハッキングを楽しめ!", + "claim_your_pixel_hack_certificate": "ピクセルハック証明書を求めよう。", + "visit_this_address_from_a_computer": "証明書を作るには、プリンターに繋がっているパソコンから次のリンクにアクセスしよう。", + "discover_kano": "Kanoを探検する", + "login": "ログイン", + "logout": "ログアウト", + "feedback": "ご意見", + "whats_up": "思ったこと", + "thank_you": "ありがとう!", + "send": "送信", + "load": "読み込む", + "load_from_where": "どこから読み込む", + "your_kano": "あなたのKanoから", + "internet": "インターネットから", + "share_by_email": "eメールで共有", + "enter_an_email_address": "メールアドレスを入力", + "i_just_made_this_with_code": "さっき、これをコードで作ったよ!あなたもやってみませんか?簡単で皆で遊べるよ。", + "your_name": "お名前…", + "next_up": "次は:", + "back_to_world": "selectedWorld.name + 'へ戻る'", + "come_back_tomorrow_to_continue": "明日戻ってきて、このチャレンジを続けよう。", + "share_on_facebook": "Facebookで共有する", + "share_on_twitter": "Twitterで共有する", + "email_address": "メールアドレス", + "share_with_friends": "友達と共有する:", + "skip_sharing": "共有しない" +} diff --git a/package.json b/package.json index a1737730f..f0b5d6b9f 100644 --- a/package.json +++ b/package.json @@ -42,11 +42,13 @@ "nib": "~1.0.x", "partialify": "^3.1.1", "throttle-debounce": "^0.1.1", - "tiny-lr": "0.0.9" + "tiny-lr": "0.0.9", + "gulp-html-i18n": "0.3.4", + "del": "1.1.1" }, "devDependencies": { - "mocha": "2.3.x", - "chai": "3.2.x" + "chai": "3.2.x", + "mocha": "2.3.x" }, "engines": { "node": "0.12.x" diff --git a/test/unit/i18n-test.js b/test/unit/i18n-test.js new file mode 100644 index 000000000..4ba0db79a --- /dev/null +++ b/test/unit/i18n-test.js @@ -0,0 +1,64 @@ +var i18n = require('../../lib/i18n'), + assert = require("chai").assert; + + +describe("i18n", function() { + beforeEach(function() { + // patch window.navigator + global.window = {}; + global.window.navigator = {}; + global.window.location = { href: '' }; + }); + + afterEach(function() { + global.window.navigator = {}; + global.window.location = {}; + }); + + it("should return users language", function() { + global.window.navigator.language = 'en-GB'; + + var lang = i18n.getLanguage(); + assert.equal(lang, 'en'); + }); + + it("should return correct challenge locale path", function() { + global.window.navigator.language = 'en-GB'; + + var challengePath = i18n.getChallengeLocalePath(); + assert.equal(challengePath, ''); + + global.window.navigator.language = 'es-AR'; + + var challengePath = i18n.getChallengeLocalePath(); + assert.equal(challengePath, '/locales/es-AR'); + }); + + it("should return correct html locale path", function() { + global.window.navigator.language = 'en-GB'; + + var challengePath = i18n.getHtmlLocalePath(); + assert.equal(challengePath, '/locales/en'); + + global.window.navigator.language = 'es-AR'; + + var challengePath = i18n.getHtmlLocalePath(); + assert.equal(challengePath, '/locales/es-AR'); + }); + + it("should allow language override from url param", function() { + global.window.navigator.language = 'en-GB'; + global.window.location.href = 'http://example.com?lang=ja'; + + var lang = i18n.getLanguage(); + assert.equal(lang, 'ja'); + }); + + it("should default to en if language is not supported", function() { + global.window.navigator.language = 'fr-FR'; + + var lang = i18n.getLanguage(); + assert.equal(lang, 'en'); + }); +}); + diff --git a/views/challenge.jade b/views/challenge.jade index aa68ee1eb..3935d0053 100644 --- a/views/challenge.jade +++ b/views/challenge.jade @@ -1,12 +1,14 @@ +include ./partial/header + .page-challenge: .page-width .workspace-header(ng-class='(animationClass || "") + (completed ? " success" : "") + (fatherDay ? " father-day" : "")') .inner.center(ng-if='!started') - h3 Challenge {{ id }}: {{ challenges[ id - 1 ].title }} + h3 ${{ challenge.challenge_title }}$ {{ challenges[ id - 1 ].title }} h4 {{ challenges[ id - 1 ].description }} - button.button-success(ng-click='start()') Start + button.button-success(ng-click='start()') ${{ challenge.start }}$ .inner(ng-if='started && !completed') @@ -15,7 +17,7 @@ ng-class='{ active: showSolution, "animate-pulse-highlight": highlightHelp }' ) i.icon-hint - | Hint + | ${{ challenge.hint }}$ progress-circle(value='step', max='content.steps.length') h3 {{ challenges[ id - 1 ].title }} @@ -25,10 +27,10 @@ .completion .text h4 {{ successMessage() }} - a.button.button-success(ng-click='goToNext()') {{ next ? 'Next' : 'Done' }} › + a.button.button-success(ng-click='goToNext()') {{ next ? '${{ challenge.next }}$' : '${{ challenge.done }}$' }} › .gallery(ng-if='content.gallery') - h4 Can you hack this challenge? + h4 ${{ challenge.can_you_hack_this_challenge }}$ .remixes .image( ng-repeat='remix in content.gallery.remixes', @@ -41,11 +43,10 @@ img(src='/assets/layout/father-day-closed.png') - h4 Make it into a Father's day card! + h4 ${{ challenge.make_it_into_a_fathers_day_card }}$ p. - Now sign-up to Kano World to share your creation and send - a card to your dad! + ${{ challenge.now_sign_up_to_kano_world_to_share_your_creation }}$ a.button.large.button-success(ng-click='login()', href='#') Log In / Sign Up @@ -53,10 +54,10 @@ img(src='/assets/layout/father-day-open.png') - h4 Share your Father's day card! + h4 ${{ challenge.share_your_fathers_day_card }}$ p. - Now you can share the card on Kano World and share it to your dad! + ${{ challenge.now_you_can_share_the_card_on_kano_world }}$ a.button.large.button-success(ng-click='shareFatherDay()', href='#') Share it! @@ -89,7 +90,7 @@ editor.solution( ng-if='showSolution && solution', ng-model='solution', - title='"Solution"' + title='"${{ challenge.solution }}$"' ) {{ solution }} .modal-overlay(ng-if='gameCompleteOpen') @@ -97,12 +98,12 @@ //- button.close(ng-click='clocseFinishedGame()'): i.icon-cross - h3 Challenges completed + h3 ${{ challenge.challenges_completed }}$ - h4(ng-if='!unlockedWorld') Now make something new! + h4(ng-if='!unlockedWorld') ${{ challenge.now_make_something_new }}$ h4(ng-if='unlockedWorld') - | New world unlocked! Play Now - + | ${{ challenge.new_world_unlocked_play_now }}$ a.button.unlocked(href='/challenges/{{ unlockedWorld.id }}') {{ unlockedWorld.name }} .logo-title @@ -111,20 +112,20 @@ a.button.secondary.large(ng-href='/challenges') i.icon-menu - | Menu + | ${{ challenge.menu }}$ a.button.large(ng-href='/playground') i.icon-game - | Playground + | ${{ challenge.playground }}$ .modal-inner.split-modal.challenge-complete.center(ng-if='selectedWorld.id === "hourofcode"') //- button.close(ng-click='clocseFinishedGame()'): i.icon-cross - h3 Challenges completed + h3 ${{ challenge.challenges_completed }}$ - h4 You did it, go back for more coding fun! + h4 ${{ challenge.you_did_it_go_back_for_more_coding_fun }}$ .hour-of-code-logo @@ -132,7 +133,7 @@ a.button.large(href='http://code.org/learn') i.icon-game - | Hour Of Code + | ${{ challenge.hour_of_code }}$ include partial/next-modal include partial/share-modal diff --git a/views/challenges.jade b/views/challenges.jade index 3b5425c52..a2260f010 100644 --- a/views/challenges.jade +++ b/views/challenges.jade @@ -1,3 +1,5 @@ +include ./partial/header + .page-challenges(ng-class="[ selectedWorldClass ]"): .page-width .image.pull-left .image.pull-right @@ -5,18 +7,18 @@ social-sharing(type='"world"' ng-if='selectedWorld.socialText && loggedIn && !offline') h3.page-title(ng-if='selectedWorld') - span {{ selectedWorld ? selectedWorld.name : 'Challenges'}} + span {{ selectedWorld ? selectedWorld.name : '${{ challenges.challenges }}$'}} .quests a(ng-if="isWorldInIndex(selectedWorld)" href='/challenges') i.icon-arrow-left - | Challenges + | ${{ challenges.challenges }}$ .header .updates-form(ng-if='selectedWorld.updateForm && !loggedIn') - h4 Get Kano Updates + h4 ${{ challenges.get_kano_updates }}$ form(name='updateForm', ng-submit='submit()') input(placeholder='Enter your email address', ng-model='formData.email', type='email', required) - button(type='submit', ng-disabled='updateForm.$invalid', ng-class='{ "disabled" : updateForm.$invalid }') Sign Up + button(type='submit', ng-disabled='updateForm.$invalid', ng-class='{ "disabled" : updateForm.$invalid }') ${{ challenges.sign_up }}$ .error(ng-if='error') {{ error }} .success(ng-if='success') {{ success }} @@ -51,7 +53,7 @@ .cover(ng-style='{"background-image": "url(/assets/challenges/images/playground.png)"}') .detail - h5 Playground + h5 ${{ challenges.playground }}$ li(ng-if='selectedWorld.certificate_after') @@ -65,7 +67,7 @@ .cover(ng-style='{"background-image": "url(/assets/challenges/images/cert-icon.png)"}') .detail - h5 Certificate + h5 ${{ challenges.certificate }}$ li(ng-if='selectedWorld.teachers_guide && !cfg.OFFLINE') a.highlight(href='/assets{{selectedWorld.teachers_guide}}',target='_blank') @@ -73,13 +75,13 @@ .cover(ng-style='{"background-image": "url(/assets/challenges/images/teachers-guide.png)"}') .detail - h5 Teacher's Guide + h5 ${{ challenges.teachers_guide }}$ div(ng-if='shares && selectedWorld.type !== "campaign"') h3.page-title i.icon-share - | Latest Shares + | ${{ challenges.latest_shares }}$ ul.shares-list @@ -103,8 +105,9 @@ .cover(ng-style='{"background-image": "url(/assets/challenges/images/browse.png)"}') .detail - h5 Browse more + h5 ${{ challenges.browse_more }}$ include ./partial/selected-challenge include ./partial/certificate-modal include ./partial/promo-popup +include ./partial/dialogs diff --git a/views/directive/auth.jade b/views/directive/auth.jade index da817fd83..2e03966e7 100644 --- a/views/directive/auth.jade +++ b/views/directive/auth.jade @@ -1,5 +1,5 @@ .close-button(ng-click='close()') × .auth-form(ng-cloak) - h3 {{mode === 'login' ? 'Login to Your Account' : 'Create your account'}} + h3 {{mode === 'login' ? '${{ directive.login_to_your_account }}$' : '${{ directive.create_your_account }}$'}} kano-login-form#kano-login-form(ng-show="mode === 'login'") kano-signup-form#kano-login-form(ng-show="mode === 'signup'") diff --git a/views/directive/display.jade b/views/directive/display.jade index b561eab76..a9f037539 100644 --- a/views/directive/display.jade +++ b/views/directive/display.jade @@ -25,25 +25,25 @@ a.action.action-share(ng-if='mode === "playground" || sharing', ng-click='setOpenModal("share")') i.icon-share - | Share + | ${{ directive.share }}$ a.action.action-save(ng-if='mode === "playground"', ng-click='save()') i.icon-save - | Save + | ${{ directive.save }}$ a.action.action-reset(ng-if='mode === "challenge"', ng-click='resetCode()') i.icon-reset - | Reset + | ${{ directive.reset }}$ .action.action-load(ng-show='mode === "playground"') i.icon-arrow-up - | Load + | ${{ directive.load }}$ input.file-load(type='file', accept='.draw') export-modal(display='this', action='"save"') export-modal(display='this', action='"share"') //- span(ng-controller='LoadDialogController' ng-if='offline') - a.button(ng-click='openDialog()') Load + a.button(ng-click='openDialog()') ${{ directive.load }}$ include partial/load diff --git a/views/directive/editor.jade b/views/directive/editor.jade index 9e8b974e8..816edd332 100644 --- a/views/directive/editor.jade +++ b/views/directive/editor.jade @@ -24,9 +24,9 @@ ul.editor-tabs(ng-if='tabbed') h4 {{ category.label }} p.hint - | Click + | ${{ directive.click_plus_to_add_a_shape_1 }}$ span.add-button - | to add a shape to your code + | ${{ directive.click_plus_to_add_a_shape_2 }}$ .command(ng-repeat='command in category.commands') @@ -59,29 +59,29 @@ div(ng-show='tab === "code"') a( href='#', ng-click='toggleAutocomplete()', - title='Toggle autocomplete', + title='${{ directive.toggle_autocomplete }}$', ng-class='{ active: autocomplete }' ) .autocomplete .round - span Autocomplete + span ${{ directive.autocomplete }}$ a( href='#', ng-click='toggleFullScreen()', - title='Toggle fullscreen', + title='${{ directive.toggle_fullscreen }}$', ng-class='{ active: fullScreen }', ng-hide='challengeId' ) .full-screen-control .round - span Fullscreen + span ${{ directive.fullscreen }}$ .editor-guide(ng-show='tab === "guide"'): .inner .teachers-guide(ng-if='teachers_guide') a.guide(ng-href='{{ "/assets" + teachers_guide }}', target='_blank') i.icon-zip - span Download teacher's guide + span ${{ directive.download_teachers_guide }}$ - h4(ng-if='guide') Guide + h4(ng-if='guide') ${{ directive.guide }}$ .guide(ng-bind-html="guide | markdown", ng-if='guide') diff --git a/views/directive/export-modal.jade b/views/directive/export-modal.jade index 9e1aaf511..3f22fd1b8 100644 --- a/views/directive/export-modal.jade +++ b/views/directive/export-modal.jade @@ -1,7 +1,7 @@ .modal-overlay(ng-if='open'): .modal-inner.export-menu button.close(ng-click='close()') × - h2.center {{ action === 'share' ? 'save to gallery' : 'save drawing' }} + h2.center {{ action === 'share' ? '${{ directive.save_to_gallery }}$' : '${{ directive.save_drawing }}$' }} .row @@ -12,17 +12,17 @@ img.created-image(ng-src='{{ imageURL }}') .col-6 - input.filename(ng-model='meta.title', placeholder='Title', type='text', required) - textarea.description(ng-model='meta.description', placeholder='Description') + input.filename(ng-model='meta.title', placeholder='${{ directive.title }}$', type='text', required) + textarea.description(ng-model='meta.description', placeholder='${{ directive.description }}$') .buttons.center button.button-success(type='submit', ng-disabled='exportForm.$invalid', ng-class='{ "disabled" : exportForm.$invalid }', ng-if='!loading') i(ng-class='"icon-" + action') - | Save + | ${{ directive.save }}$ - button.button-success.skip(ng-if='optional && !loading', ng-click='skipSharing()') Skip + button.button-success.skip(ng-if='optional && !loading', ng-click='skipSharing()') ${{ directive.skip }}$ .spinner(ng-if='loading') if offline - .center: button.export-wallpaper(style='margin-top: 10px', ng-click='exportWallpaper()', ng-disabled='exportForm.$invalid', ng-class='{ "disabled" : exportForm.$invalid }') Save Wallpaper + .center: button.export-wallpaper(style='margin-top: 10px', ng-click='exportWallpaper()', ng-disabled='exportForm.$invalid', ng-class='{ "disabled" : exportForm.$invalid }') ${{ directive.save_wallpaper }}$ diff --git a/views/directive/social.jade b/views/directive/social.jade index a3a2feb17..e2147709c 100644 --- a/views/directive/social.jade +++ b/views/directive/social.jade @@ -1,10 +1,10 @@ .social-sharing .buttons a.button.button-facebook(ng-click='facebookShare()') - img(src='/assets/button-icons/facebook-white.png' title='Share on Facebook') + img(src='/assets/button-icons/facebook-white.png' title='${{ partial.share_on_facebook }}$') a.button.button-twitter(ng-href='{{ buildURL() }}') - img(src='/assets/button-icons/twitter-white.png' title='Share on Twitter') + img(src='/assets/button-icons/twitter-white.png' title='${{ partial.share_on_twitter }}$') a.button.button-mail(ng-click='open()') i.icon-mail @@ -20,11 +20,11 @@ .box.box-danger(ng-if='error') {{ error }} .email - input(ng-model='mailForm.email', placeholder='Recipient\'s email address', type='email', required) + input(ng-model='mailForm.email', placeholder='${{ directive.recipients_email_address }}$', type='email', required) .message - textarea(ng-model='mailForm.description', placeholder='Your message', required) + textarea(ng-model='mailForm.description', placeholder='${{ directive.your_message }}$', required) - button.button-success(type='submit', ng-disabled='form.$invalid', ng-class='{ "disabled" : form.$invalid }', ng-if='!loading') Send + button.button-success(type='submit', ng-disabled='form.$invalid', ng-class='{ "disabled" : form.$invalid }', ng-if='!loading') ${{ partial.send }}$ - .spinner(ng-if='loading') \ No newline at end of file + .spinner(ng-if='loading') diff --git a/views/index.jade b/views/index.jade index dfbac8843..9f04b9efa 100644 --- a/views/index.jade +++ b/views/index.jade @@ -24,40 +24,28 @@ html(lang='en', xmlns:ng="http://angularjs.org") script(src='/js/vendor/xtag.js') body(id="ng-app", ng-app='draw', class=offline ? 'offline' : 'online') - // Google Tag Manager + //- Google Tag Manager noscript - iframe(src='//www.googletagmanager.com/ns.html?id=discover-kano', height='0', width='0', style='display:none;visibility:hidden') - script. + iframe(src='//www.googletagmanager.com/ns.html?id=GTM-WMGKFR', height='0', width='0', style='display: none; visibility: hidden;') + script(type='text/javascript'). (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= '//www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); - })(window,document,'script','dataLayer','discover-kano'); - // End Google Tag Manager + })(window,document,'script','dataLayer','GTM-WMGKFR'); + //- End Google Tag Manager script(src='/js/vendor/console-polyfill.js', type='text/javascript') .loading-overlay(ng-cloak): .spinner - include partial/header ng-view include partial/splash - if !offline - .kano-feedback-container(ng-click='isFeedbackSplashOpen = true', ng-init='feedbackLoaded()') - span Feedback - .kano-feedback - include partial/feedback - include partial/auth-modal - - //- Vendor script(src='/js/vendor/angular.min.js', type='text/javascript') script(src='/js/vendor/angular-route.min.js', type='text/javascript') script(src='/js/vendor/ace/ace.js', type='text/javascript') script(src='/js/vendor/ace/ext-language_tools.js', type='text/javascript') - //- Analytics - if segmentioId - script(src='/js/vendor/segmentio.min.js', type='text/javascript') script(type='text/javascript'). window.ENV = '#{env}'; diff --git a/views/partial/banner.jade b/views/partial/banner.jade index 09f74fa20..48a5b70da 100644 --- a/views/partial/banner.jade +++ b/views/partial/banner.jade @@ -1,7 +1,7 @@ .banner(ng-if='selectedWorld.id !== "pixelhack"') a(href="/challenges/pixelhack") - span Pixel Hack: - | code your way through the history of video game art. + span ${{ partial.pixel_hack }}$ + | ${{ partial.code_your_way_through_the_history }}$ .modal-overlay(ng-if='banner.showModal') .modal-inner.modal-challenge-info.center(ng-style="{'display': banner.showModal ? 'block' : 'none'}") @@ -11,7 +11,7 @@ button.close(ng-click='banner.closeModal()'): i.icon-cross .detail - h3 Welcome to Pixel Hack + h3 ${{ partial.welcome_to_pixel_hack }}$ - p Start your coding adventure by drawing Pong and other retro games. Move on to master 8-bit art for your own Minecraft characters and more. Show us how you can hack our challenges. Earn your Pixel Master Badge. - p Happy Hacking! \ No newline at end of file + p ${{ partial.start_your_coding_adventure }}$ + p ${{ partial.happy_hacking }}$ diff --git a/views/partial/certificate-modal.jade b/views/partial/certificate-modal.jade index 35140eb6b..e17ddcc3f 100644 --- a/views/partial/certificate-modal.jade +++ b/views/partial/certificate-modal.jade @@ -6,8 +6,8 @@ button.close(ng-click='toggleCertModal()'): i.icon-cross .detail - h3 Claim your Pixel Hack certificate. + h3 ${{ partial.claim_your_pixel_hack_certificate }}$ - p Visit this address from a computer with a connected printer to create your certificate. + p ${{ partial.visit_this_address_from_a_computer }}$ - h3 http://certificate.kano.me/pixelhack/ \ No newline at end of file + h3 http://certificate.kano.me/pixelhack/ diff --git a/views/partial/dialogs.jade b/views/partial/dialogs.jade new file mode 100644 index 000000000..c9ea996d2 --- /dev/null +++ b/views/partial/dialogs.jade @@ -0,0 +1,8 @@ + +if !offline + .kano-feedback-container(ng-click='feedback.openModal()', ng-init='feedbackLoaded()') + span ${{ partial.feedback }}$ + .kano-feedback + include ./feedback + include ./auth-modal + diff --git a/views/partial/feedback.jade b/views/partial/feedback.jade index d239fa60d..7459183a1 100644 --- a/views/partial/feedback.jade +++ b/views/partial/feedback.jade @@ -1,8 +1,8 @@ -.modal-overlay(ng-controller='FeedbackController', ng-if='isFeedbackSplashOpen', ng-cloak) +.modal-overlay(ng-controller='FeedbackController', ng-if='feedback.showModal', ng-cloak) .modal-inner.split-modal.splash.feedback-splash - button.close(ng-click='handleSkip($event)'): i.icon-cross + button.close(ng-click='closeModal()'): i.icon-cross form(name='form' ng-submit='sendFeedback()') - h1.center: b Feedback + h1.center: b ${{ partial.feedback }}$ .box.box-danger(ng-if='error') {{ error }} @@ -20,11 +20,11 @@ .mood-container: label(class='mood rating-5', for='rating_5') .feedback-box - textarea(ng-model='feedback.thought', rows="3", placeholder='What\'s up?', required) + textarea(ng-model='feedback.thought', rows="3", placeholder='${{ partial.whats_up }}$', required) .form-message.hide - h3 Thank you! + h3 ${{ partial.thank_you }}$ .center.bottom-section: div(style='min-height: 88px'): .feedback-buttons - button.button.large(type='submit', ng-disabled='form.$invalid', ng-class='{ "disabled" : form.$invalid }', ng-if='!loading') Send - .spinner(ng-if='loading') \ No newline at end of file + button.button.large(type='submit', ng-disabled='form.$invalid', ng-class='{ "disabled" : form.$invalid }', ng-if='!loading') ${{ partial.send }}$ + .spinner(ng-if='loading') diff --git a/views/partial/header.jade b/views/partial/header.jade index a84aac3b4..1b7ce8ede 100644 --- a/views/partial/header.jade +++ b/views/partial/header.jade @@ -8,20 +8,20 @@ header: .page-width li: a(href='/challenges', ng-class='{ active: basePath === "challenge" || basePath === "challenges" }') i.icon-menu - | Challenges + | ${{ challenges.challenges }}$ li: a(href='/playground', ng-class='{ active: basePath === "playground" }') i.icon-game - | Playground + | ${{ challenges.playground }}$ ul.nav.nav-right(ng-cloak) li.discover: a(ng-if="!offline" id='discover-kano', href='http://www.kano.me', target='_blank') i.icon-cpu - | Discover Kano + | ${{ partial.discover_kano }}$ li(ng-if='!offline && !loggedIn'): a(href='#', ng-click='auth.openModal()') i.icon-login - | Login + | ${{ partial.login }}$ li(ng-if='!offline && loggedIn') @@ -31,7 +31,7 @@ header: .page-width li(ng-if='!offline && loggedIn'): a(href='#', ng-click='logout()') i.icon-logout - | Logout + | ${{ partial.logout }}$ li: button.close(ng-click='shutdown()', ng-if='offline'): i.icon-cross diff --git a/views/partial/load.jade b/views/partial/load.jade index fda7ccff3..be9fadda4 100644 --- a/views/partial/load.jade +++ b/views/partial/load.jade @@ -1,11 +1,11 @@ .modal-overlay(ng-show='isOpen'): .modal-inner.split-modal.load-menu button.close(ng-click='isOpen = false') × - h2.center Load - h4.center Load from where + h2.center ${{ partial.load }}$ + h4.center ${{ partial.load_from_where }}$ .bottom-section.center span - button.button.large() Your Kano + button.button.large() ${{ partial.your_kano }}$ input.transparent(type='file' accept='.draw' onChange='angular.element(this).scope().load(this)') - button.button.large(ng-click='load.web()') Internet + button.button.large(ng-click='load.web()') ${{ partial.internet }}$ diff --git a/views/partial/mail-preview.jade b/views/partial/mail-preview.jade index f157e70eb..006d11664 100644 --- a/views/partial/mail-preview.jade +++ b/views/partial/mail-preview.jade @@ -2,16 +2,16 @@ .modal-inner.modal-mail-preview.center button.close(ng-click='closePreview()'): i.icon-cross .preview - .header Share by email + .header ${{ partial.share_by_email }}$ h4 "{{ selectedSummerChallengeObj.shareTitle }}" .content .left-content - input(type='email' ng-model='selectedSummerChallengeObj.email' placeholder='Enter an email address') - textarea(ng-model='selectedSummerChallengeObj.message' placeholder="I just made this with code! Want to try your own? It's easy, fun and for everyone") - input(type='text' ng-model='selectedSummerChallengeObj.name' placeholder='Your name...') + input(type='email' ng-model='selectedSummerChallengeObj.email' placeholder='${{ partial.enter_an_email_address }}$') + textarea(ng-model='selectedSummerChallengeObj.message' placeholder="${{ partial.i_just_made_this_with_code }}$") + input(type='text' ng-model='selectedSummerChallengeObj.name' placeholder='${{ partial.your_name }}$') .right-content .pic img(ng-src='{{selectedSummerChallengeObj.img}}' ng-if='!selectedSummerChallengeObj.cover_url') img(ng-src='{{selectedSummerChallengeObj.cover_url}}' ng-if='selectedSummerChallengeObj.cover_url') - a.button.button-success(ng-click='sendMail(selectedSummerChallengeObj)') Send \ No newline at end of file + a.button.button-success(ng-click='sendMail(selectedSummerChallengeObj)') ${{ partial.send }}$ diff --git a/views/partial/next-modal.jade b/views/partial/next-modal.jade index 25e958fce..0e8c5e507 100644 --- a/views/partial/next-modal.jade +++ b/views/partial/next-modal.jade @@ -8,16 +8,16 @@ .detail .title - | Next up: + | ${{ partial.next_up }}$ span {{ next.title }} - a.button.button-success(ng-href='/challenges/{{selectedWorld.id}}' ng-if='next.locked') {{ selectedWorld ? 'Back to ' + selectedWorld.name : 'Menu' }} + a.button.button-success(ng-href='/challenges/{{selectedWorld.id}}' ng-if='next.locked') {{ selectedWorld ? ${{ partial.back_to_world }}$ : '${{ challenge.menu }}$' }} - a.button.button-success(ng-href='/challenge/{{selectedWorld.id}}/{{next.id}}' ng-if='!next.locked') Start + a.button.button-success(ng-href='/challenge/{{selectedWorld.id}}/{{next.id}}' ng-if='!next.locked') ${{ challenge.start }}$ p.description {{ next.description }} - p.description.small(ng-if='next.locked') Come back tomorrow to continue this challenge + p.description.small(ng-if='next.locked') ${{ partial.come_back_tomorrow_to_continue }}$ .social-sharing(ng-if='creation && !mailTab') @@ -33,13 +33,13 @@ i.icon-mail a.button.button-facebook(ng-click='facebookShare(creation)') - img(src='/assets/button-icons/facebook-white.png' title='Share on Facebook') + img(src='/assets/button-icons/facebook-white.png' title='${{ partial.share_on_facebook }}$') a.button.button-twitter(target='_new', ng-href='{{ buildURL(creation) }}') - img(src='/assets/button-icons/twitter-white.png' title='Share on Twitter') + img(src='/assets/button-icons/twitter-white.png' title='${{ partial.share_on_twitter }}$') .mail-tab.center(ng-if='mailTab') - span Share by email + span ${{ partial.share_by_email }}$ form(ng-submit='sendMail(creation)' name='mailForm') .box.box-danger(ng-if='error') {{ error }} @@ -47,6 +47,6 @@ .email input(ng-model='creation.email', placeholder='Email address', type='email', required) - button.button-success(type='submit', ng-disabled='mailForm.$invalid', ng-class='{ "disabled" : mailForm.$invalid }', ng-if='!loading') Send + button.button-success(type='submit', ng-disabled='mailForm.$invalid', ng-class='{ "disabled" : mailForm.$invalid }', ng-if='!loading') ${{ partial.send }}$ - .spinner(ng-if='loading') \ No newline at end of file + .spinner(ng-if='loading') diff --git a/views/partial/selected-challenge.jade b/views/partial/selected-challenge.jade index 6b15ccce1..f60f0f2e1 100644 --- a/views/partial/selected-challenge.jade +++ b/views/partial/selected-challenge.jade @@ -11,4 +11,4 @@ p.description {{ selectedChallenge.description }} - a.button.button-success(ng-href='/challenge/{{selectedWorld.id}}/{{selectedChallenge.id}}') Start \ No newline at end of file + a.button.button-success(ng-href='/challenge/{{selectedWorld.id}}/{{selectedChallenge.id}}') ${{ challenge.start }}$ diff --git a/views/partial/share-modal.jade b/views/partial/share-modal.jade index 262f89b8c..d6690987e 100644 --- a/views/partial/share-modal.jade +++ b/views/partial/share-modal.jade @@ -13,28 +13,28 @@ p.description {{ creation.description }} .buttons(ng-if='!mailTab') - | Share with friends: + | ${{ partial.share_with_friends }}$ a.button.button-mail(ng-click='openMailTab()') i.icon-mail a.button.button-facebook(ng-click='facebookShare(creation)') - img(src='/assets/button-icons/facebook-white.png' title='Share on Facebook') + img(src='/assets/button-icons/facebook-white.png' title='${{ partial.share_on_facebook }}$') a.button.button-twitter(ng-href='{{ buildURL(creation) }}') - img(src='/assets/button-icons/twitter-white.png' title='Share on Twitter') + img(src='/assets/button-icons/twitter-white.png' title='${{ partial.share_on_twitter }}$') .skip-sharing(ng-if='selectedWorld.share_strategy === "optional"') - button.button-success(ng-click='skipSocialSharing()') Skip Sharing + button.button-success(ng-click='skipSocialSharing()') ${{ partial.skip_sharing }}$ .mail-tab.center(ng-if='mailTab') - span Share by email + span ${{ partial.share_by_email }}$ form(ng-submit='sendMail(creation)' name='mailForm') .box.box-danger(ng-if='error') {{ error }} .email - input(ng-model='creation.email', placeholder='Email address', type='email', required) + input(ng-model='creation.email', placeholder='${{ partial.email_address }}$', type='email', required) - button.button-success(type='submit', ng-disabled='mailForm.$invalid', ng-class='{ "disabled" : mailForm.$invalid }', ng-if='!loading') Send + button.button-success(type='submit', ng-disabled='mailForm.$invalid', ng-class='{ "disabled" : mailForm.$invalid }', ng-if='!loading') ${{ partial.send }}$ .spinner(ng-if='loading') diff --git a/views/playground.jade b/views/playground.jade index cf1a12c7e..ae953f00d 100644 --- a/views/playground.jade +++ b/views/playground.jade @@ -1,3 +1,5 @@ +include ./partial/header + .page-width: .workspace .workspace-body: .row diff --git a/views/share.jade b/views/share.jade index a165e5cb5..006cca6c9 100644 --- a/views/share.jade +++ b/views/share.jade @@ -1,5 +1,7 @@ +include ./partial/header + section: .page-width .box.center(ng-if='!error') Loading share… .box.box-danger.center(ng-if='error') strong Error: - | {{ error }} \ No newline at end of file + | {{ error }} diff --git a/www.zip b/www.zip index ba295cf00..9664a0b09 100644 Binary files a/www.zip and b/www.zip differ